package com.yuexunit.finance.project.action.v1;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.yuexunit.core.BusinessException;
import com.yuexunit.finance.bulkstock.entity.BulkstockInfoEntity;
import com.yuexunit.finance.common.util.BeanUtils;
import com.yuexunit.finance.common.util.CollectionUtils;
import com.yuexunit.finance.common.util.CreateSimpleExcelToDisk;
import com.yuexunit.finance.common.util.DateUtils;
import com.yuexunit.finance.common.util.LongUtils;
import com.yuexunit.finance.context.FinanceBaseAction;
import com.yuexunit.finance.context.FinanceConstant;
import com.yuexunit.finance.context.FinanceLetterBlockingQueue;
import com.yuexunit.finance.context.FinanceSessionContext;
import com.yuexunit.finance.member.entity.LogisticsCompanyEntity;
import com.yuexunit.finance.member.entity.MonthEarningDetailEntity;
import com.yuexunit.finance.member.entity.MonthEarningEntity;
import com.yuexunit.finance.member.entity.SupplierEntity;
import com.yuexunit.finance.member.entity.lexicon.AuditStateEnum;
import com.yuexunit.finance.member.entity.lexicon.RepayStateEnum;
import com.yuexunit.finance.member.service.LogisticsCompanyService;
import com.yuexunit.finance.member.service.MonthEarningDetailService;
import com.yuexunit.finance.member.service.MonthEarningService;
import com.yuexunit.finance.member.service.SupplierService;
import com.yuexunit.finance.project.action.v1.dto.BulkstockPledgeCastor;
import com.yuexunit.finance.project.action.v1.dto.FinanceLoanCastor;
import com.yuexunit.finance.project.action.v1.dto.FinanceProcessCastor;
import com.yuexunit.finance.project.action.v1.model.FinanceMoneyStatement;
import com.yuexunit.finance.project.action.v1.model.FinanceOtherMoneyStatement;
import com.yuexunit.finance.project.action.v1.model.InterestEstimate;
import com.yuexunit.finance.project.action.v1.model.Receivables;
import com.yuexunit.finance.project.action.v1.model.input.FinanceWriteoffParams;
import com.yuexunit.finance.project.action.v1.model.input.LoanNoticeConsentParams;
import com.yuexunit.finance.project.action.v1.model.input.LoanNoticeParams;
import com.yuexunit.finance.project.action.v1.model.input.LoanNoticeUpdateParams;
import com.yuexunit.finance.project.action.v1.model.input.ReceivablesConsentParams;
import com.yuexunit.finance.project.action.v1.model.input.ReceivablesUpdateParams;
import com.yuexunit.finance.project.action.v1.model.output.BillReceivableDetail;
import com.yuexunit.finance.project.action.v1.model.output.Capital;
import com.yuexunit.finance.project.action.v1.model.output.FinanceCreditDetail;
import com.yuexunit.finance.project.action.v1.model.output.FinanceCreditLineInfo;
import com.yuexunit.finance.project.action.v1.model.output.FinanceWriteoffDetail;
import com.yuexunit.finance.project.action.v1.model.output.FinanceWriteoffLineInfo;
import com.yuexunit.finance.project.action.v1.model.output.InterestDelayDetail;
import com.yuexunit.finance.project.action.v1.model.output.InterestDelayLineInfo;
import com.yuexunit.finance.project.action.v1.model.output.LoanNoticeDetail;
import com.yuexunit.finance.project.action.v1.model.output.LoanNoticeLineInfo;
import com.yuexunit.finance.project.action.v1.model.output.PickupApplicationWarehouseDetail;
import com.yuexunit.finance.project.action.v1.model.output.PickupBulkstockWarehouseDetail;
import com.yuexunit.finance.project.action.v1.model.output.QuarterSettlementLineInfo;
import com.yuexunit.finance.project.action.v1.model.output.ReceivablesDetail;
import com.yuexunit.finance.project.action.v1.model.output.ReceivablesLineInfo;
import com.yuexunit.finance.project.entity.BillReceivableEntity;
import com.yuexunit.finance.project.entity.ContainerBulkstockEntity;
import com.yuexunit.finance.project.entity.ContainerInventoryEntity;
import com.yuexunit.finance.project.entity.FinanceApplicationEntity;
import com.yuexunit.finance.project.entity.FinanceAuditEntity;
import com.yuexunit.finance.project.entity.FinanceAuditLogEntity;
import com.yuexunit.finance.project.entity.FinanceBulkstockEntity;
import com.yuexunit.finance.project.entity.FinanceCompleteResultEntity;
import com.yuexunit.finance.project.entity.FinanceContainerEntity;
import com.yuexunit.finance.project.entity.FinanceContainerLogEntity;
import com.yuexunit.finance.project.entity.FinanceCreditBulkstockEntity;
import com.yuexunit.finance.project.entity.FinanceCreditContainerBulkstockEntity;
import com.yuexunit.finance.project.entity.FinanceCreditContainerEntity;
import com.yuexunit.finance.project.entity.FinanceCreditEntity;
import com.yuexunit.finance.project.entity.FinanceCreditReplenishContainerEntity;
import com.yuexunit.finance.project.entity.FinanceCreditReplenishEntity;
import com.yuexunit.finance.project.entity.FinanceFilesInfoEntity;
import com.yuexunit.finance.project.entity.FinanceMoneyStatementEntity;
import com.yuexunit.finance.project.entity.FinanceOtherMoneyStatementEntity;
import com.yuexunit.finance.project.entity.FinanceProcessDetailEntity;
import com.yuexunit.finance.project.entity.FinanceProcessEntity;
import com.yuexunit.finance.project.entity.FinanceProductEntity;
import com.yuexunit.finance.project.entity.FinanceProductInnerEntity;
import com.yuexunit.finance.project.entity.FinanceProductInterestItemEntity;
import com.yuexunit.finance.project.entity.FinanceRecordCorrespondingInfoEntity;
import com.yuexunit.finance.project.entity.FinanceWriteoffEntity;
import com.yuexunit.finance.project.entity.FinanceWriteoffStatementEntity;
import com.yuexunit.finance.project.entity.InsuranceEntity;
import com.yuexunit.finance.project.entity.InterestDelayApplicationEntity;
import com.yuexunit.finance.project.entity.LoanNoticeEntity;
import com.yuexunit.finance.project.entity.PickupApplicationEntity;
import com.yuexunit.finance.project.entity.PickupBulkstockEntity;
import com.yuexunit.finance.project.entity.PickupInventoryEntity;
import com.yuexunit.finance.project.entity.QuarterSettlementContainerEntity;
import com.yuexunit.finance.project.entity.QuarterSettlementEntity;
import com.yuexunit.finance.project.entity.ReceiptRecordEntity;
import com.yuexunit.finance.project.entity.ReceivablesEntity;
import com.yuexunit.finance.project.entity.RecieveNoticeEntity;
import com.yuexunit.finance.project.entity.lexicon.AbnormalResultEnum;
import com.yuexunit.finance.project.entity.lexicon.AbnormalStateEnum;
import com.yuexunit.finance.project.entity.lexicon.AbnormalTypeEnum;
import com.yuexunit.finance.project.entity.lexicon.AdjustmentEnum;
import com.yuexunit.finance.project.entity.lexicon.ApiFinanceStateEnum;
import com.yuexunit.finance.project.entity.lexicon.ApiTypeEnum;
import com.yuexunit.finance.project.entity.lexicon.ApplicantLoanStateEnum;
import com.yuexunit.finance.project.entity.lexicon.ApplicationSimpleStateEnum;
import com.yuexunit.finance.project.entity.lexicon.ApplicationStateEnum;
import com.yuexunit.finance.project.entity.lexicon.BadassetsStateEnum;
import com.yuexunit.finance.project.entity.lexicon.BillTypeEnum;
import com.yuexunit.finance.project.entity.lexicon.BillingMethodEnum;
import com.yuexunit.finance.project.entity.lexicon.BulkstockSourceEnum;
import com.yuexunit.finance.project.entity.lexicon.ConstractStateEnum;
import com.yuexunit.finance.project.entity.lexicon.DeliveryMethodEnum;
import com.yuexunit.finance.project.entity.lexicon.FileSignStateEnum;
import com.yuexunit.finance.project.entity.lexicon.FinanceAuditEnum;
import com.yuexunit.finance.project.entity.lexicon.FinanceConstractStateEnum;
import com.yuexunit.finance.project.entity.lexicon.FinanceStateEnum;
import com.yuexunit.finance.project.entity.lexicon.LoanMethodEnum;
import com.yuexunit.finance.project.entity.lexicon.OperatorRoleEnum;
import com.yuexunit.finance.project.entity.lexicon.PickupMethodEnum;
import com.yuexunit.finance.project.entity.lexicon.PickupModelEnum;
import com.yuexunit.finance.project.entity.lexicon.PickupTypeEnum;
import com.yuexunit.finance.project.entity.lexicon.ProductTypeEnum;
import com.yuexunit.finance.project.entity.lexicon.ReplenishEnum;
import com.yuexunit.finance.project.entity.lexicon.ReplenishMethodEnum;
import com.yuexunit.finance.project.entity.lexicon.ReplenishStateEnum;
import com.yuexunit.finance.project.entity.lexicon.SupervisionStateEnum;
import com.yuexunit.finance.project.entity.lexicon.WriteoffTypeEnum;
import com.yuexunit.finance.project.service.BillReceivableService;
import com.yuexunit.finance.project.service.FinanceAuditLogService;
import com.yuexunit.finance.project.service.FinanceFilesInfoService;
import com.yuexunit.finance.project.service.FinanceMoneyStatementService;
import com.yuexunit.finance.project.service.FinanceOtherMoneyStatementService;
import com.yuexunit.finance.project.service.FinanceProductInnerService;
import com.yuexunit.finance.project.service.FinanceProductInterestItemService;
import com.yuexunit.finance.project.service.FinanceProductService;
import com.yuexunit.finance.project.service.FinanceRecordCorrespondingInfoService;
import com.yuexunit.finance.project.service.FinanceWriteoffService;
import com.yuexunit.finance.project.service.FinanceWriteoffStatementService;
import com.yuexunit.finance.project.service.InsuranceService;
import com.yuexunit.finance.project.service.LoanNoticeService;
import com.yuexunit.finance.project.service.QuarterSettlementContainerService;
import com.yuexunit.finance.project.service.QuarterSettlementService;
import com.yuexunit.finance.project.service.ReceiptRecordService;
import com.yuexunit.finance.project.service.RecieveNoticeService;
import com.yuexunit.finance.system.action.v1.SystemParamActionApi;
import com.yuexunit.finance.system.action.v1.dto.SendLetterMessage;
import com.yuexunit.finance.system.entity.CapitalAccountInfoEntity;
import com.yuexunit.finance.system.entity.SignFileInfoEntity;
import com.yuexunit.finance.system.service.BankInfoService;
import com.yuexunit.finance.system.service.SignFileInfoService;
import com.yuexunit.finance.system.service.SystemParamService;
import com.yuexunit.inject.ComponentFactory;
import com.yuexunit.inject.annotation.Implements;
import com.yuexunit.page.PageCriteria;
import com.yuexunit.page.PageList;
import com.yuexunit.permission.action.PermissionActionsApi;
import com.yuexunit.permission.action.dto.RoleListDto;
import com.yuexunit.persist.annotation.Transactional;
import com.yuexunit.persist.hibernate.SessionRepository;
import com.yuexunit.util.DateUtil;
import com.yuexunit.util.StringUtil;

@Implements(FinanceLoanActionApi.class)
public class FinanceLoanActionApiImpl extends FinanceBaseAction implements FinanceLoanActionApi {
	
	public static Logger logger = LoggerFactory.getLogger(FinanceLoanActionApiImpl.class);

	private FinanceMoneyStatementService financeMoneyStatementService = ComponentFactory.loadClass(FinanceMoneyStatementService.class);

	private FinanceWriteoffService financeWriteoffService = ComponentFactory.loadClass(FinanceWriteoffService.class);

	private FinanceWriteoffStatementService financeWriteoffStatementService = ComponentFactory.loadClass(FinanceWriteoffStatementService.class);

	private QuarterSettlementService quarterSettlementService = ComponentFactory.loadClass(QuarterSettlementService.class);

	private QuarterSettlementContainerService quarterSettlementContainerService = ComponentFactory.loadClass(QuarterSettlementContainerService.class);

	private LoanNoticeService loanNoticeService = ComponentFactory.loadClass(LoanNoticeService.class);

	private BankInfoService bankInfoService = ComponentFactory.loadClass(BankInfoService.class);

	private InsuranceService insuranceService = ComponentFactory.loadClass(InsuranceService.class);

	private BillReceivableService billReceivableService = ComponentFactory.loadClass(BillReceivableService.class);
	
	private FinanceProductService financeProductService = ComponentFactory.loadClass(FinanceProductService.class);
	
	private FinanceAuditLogService financeAuditLogService = ComponentFactory.loadClass(FinanceAuditLogService.class);
	
	private FinanceBulkstockNoticeActionApi financeBulkstockNoticeActionApi = ComponentFactory.loadClass(FinanceBulkstockNoticeActionApi.class);
	
	private RecieveNoticeService recieveNoticeService = ComponentFactory.loadClass(RecieveNoticeService.class);
	
	private FinanceOtherMoneyStatementService financeOtherMoneyStatementService = ComponentFactory.loadClass(FinanceOtherMoneyStatementService.class);
	
	private LogisticsCompanyService logisticsCompanyService = ComponentFactory.loadClass(LogisticsCompanyService.class);
	
	private SystemParamService systemParamService = ComponentFactory.loadClass(SystemParamService.class);
	
	private SupplierService supplierService = ComponentFactory.loadClass(SupplierService.class);
	
	private SignFileInfoService signFileInfoService = ComponentFactory.loadClass(SignFileInfoService.class);
	
	private FinanceFilesInfoService financeFilesInfoService = ComponentFactory.loadClass(FinanceFilesInfoService.class);
	
	private FinancePickupApplicationWarehouseApi financePickupApplicationWarehouseApi = ComponentFactory.loadClass(FinancePickupApplicationWarehouseApi.class);
	
	private FinanceProductInterestItemService financeProductInterestItemService = ComponentFactory.loadClass(FinanceProductInterestItemService.class);
	
	private FinanceProductInnerService financeProductInnerService = ComponentFactory.loadClass(FinanceProductInnerService.class);
	
	private FinanceApplicationActionApi financeApplicationActionApi = ComponentFactory.loadClass(FinanceApplicationActionApi.class);
	
	private SystemParamActionApi systemParamActionApi = ComponentFactory.loadClass(SystemParamActionApi.class);
	
	private ReceiptRecordService receiptRecordService = ComponentFactory.loadClass(ReceiptRecordService.class);
	
	private FinanceRecordCorrespondingInfoService financeRecordCorrespondingInfoService = ComponentFactory.loadClass(FinanceRecordCorrespondingInfoService.class);
	
	private MonthEarningService monthEarningService = ComponentFactory.loadClass(MonthEarningService.class);
	
	private MonthEarningDetailService monthEarningDetailService = ComponentFactory.loadClass(MonthEarningDetailService.class);
	
	private String tmp = "客户(%s)融资(%s)目前处于放款审批环节对应的(%s)节点，请及时审批！";

	/** 补货确认-合并至融资货物 */
	private Map<Long, FinanceBulkstockEntity> processFinanceReplenishBulkstockCredit(FinanceCreditEntity credit, List<FinanceCreditReplenishEntity> replenishs) {
		Map<Long, FinanceBulkstockEntity> bulkstocks = new HashMap<>();
		for (FinanceCreditReplenishEntity replenish : replenishs) {
			// 合并至融资货物中
			FinanceBulkstockEntity bulkstock = new FinanceBulkstockEntity();
			BeanUtils.copyProperties(replenish, bulkstock);
			bulkstock.setBulkstockSource(BulkstockSourceEnum.CREDIT);
			bulkstock.setReplenishCreditId(credit.getCreditId());
			bulkstock.setFinanceId(credit.getFinanceId());
			bulkstock.setCargoMark(null);
			bulkstock.setColdStorage(Boolean.FALSE);
			bulkstock.setDangerous(Boolean.FALSE);
			bulkstock.setPublicity(Boolean.FALSE);
			bulkstock.setAbnormal(BigDecimal.ZERO);
			bulkstock.setPickup(BigDecimal.ZERO);
			bulkstock.setHarbor(BigDecimal.ZERO);
			if (ReplenishMethodEnum.CONTAINER == credit.getReplenishMethod()) { // 补箱
				bulkstock.setRecieve(replenish.getQuantity());
				bulkstock.setSupervision(replenish.getQuantity());
				bulkstock.setIncustody(replenish.getQuantity());
			} else { // 换货需要通知收货流程
				bulkstock.setRecieve(BigDecimal.ZERO);
				bulkstock.setSupervision(BigDecimal.ZERO);
				bulkstock.setIncustody(BigDecimal.ZERO);
			}
			financeBulkstockService.createFinanceBulkstockEntity(bulkstock);
			bulkstocks.put(bulkstock.getBulkstockInfoId(), bulkstock);
			replenish.setBulkstockId(bulkstock.getBulkstockId());
		}
		return bulkstocks;
	}

	/** 补箱确认-合并至箱信息 */
	private void processFinanceReplenishContainerCredit(Map<Long, FinanceBulkstockEntity> bulkstocks, FinanceCreditEntity credit) {
		BigDecimal currentReplenishFinanceAmount = credit.getReplenishFinanceAmount();
		ContainerInventoryEntity ci = containerInventoryService.inquireLoanNoticeContainerInventoryList(credit.getLoanNoticeId()).get(0);
		FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(credit.getFinanceId());
		List<FinanceCreditContainerBulkstockEntity> list = financeCreditContainerBulkstockService.inquireFinanceCreditContainerBulkstockList(credit.getCreditId());
		Map<Long, FinanceCreditContainerBulkstockEntity> fccbs = new HashMap<>();
		for (FinanceCreditContainerBulkstockEntity fccb : list) {
			fccbs.put(fccb.getContainerId(), fccb);
		}
		List<FinanceCreditContainerEntity> fccs = financeCreditContainerService.inquireFinanceCreditContainerList(credit.getCreditId());
		for (int i = 0; i < fccs.size(); i++) {
			FinanceCreditContainerEntity fcc = fccs.get(i);
			ContainerInventoryEntity cie = new ContainerInventoryEntity();
			cie.setContainerSource(BulkstockSourceEnum.CREDIT);
			cie.setExchangePickupId(null);
			cie.setReplenishCreditId(credit.getCreditId());
			cie.setEnterpriseId(finance.getEnterpriseId());
			cie.setEnterpriseName(finance.getEnterpriseName());
			cie.setFinanceId(finance.getFinanceId());
			cie.setFinanceNumber(finance.getFinanceNumber());
			cie.setRecieveNoticeId(null);
			cie.setTallyingId(null);
			cie.setTallyingCompanyId(null);
			cie.setConfirmationId(null);
			cie.setLoanNoticeId(credit.getLoanNoticeId());
			cie.setTransportNoticeId(null);
			cie.setTransportCompanyId(null);
			cie.setPickupId(null);
			cie.setDeliveryCompanyId(null);
			cie.setDeliveryId(null);
			cie.setDeliveryNoticeId(null);
			cie.setPickupModel(PickupModelEnum.UNKNOWN);
			cie.setWaybillNumber(fcc.getWaybillNumber());
			cie.setCaseNumber(fcc.getCaseNumber());
			cie.setCaseSize(fcc.getCaseSize());
			cie.setModel(cie.getCaseSize().replaceAll("[^0-9]", ""));
			cie.setDimension(cie.getCaseSize().replaceAll("[0-9]", ""));
			cie.setFacingSlip(fcc.getFacingSlip());
			cie.setFacingSlipNext(null);
			cie.setAbnormal(Boolean.TRUE);
			cie.setAbnormalState(AbnormalStateEnum.UNKNOWN);
			cie.setAbnormalType(AbnormalTypeEnum.UNKNOWN);
			cie.setLatestAbnormalResult(AbnormalResultEnum.UNKNOWN);
			cie.setTallyingState(Boolean.TRUE);
			cie.setTallyDateTime(DateUtils.now());
			cie.setHarborState(Boolean.FALSE);
			cie.setHarborDateTime(null);
			cie.setShipsName(null);
			cie.setVoyageNumber(null);
			cie.setSignState(Boolean.FALSE);
			cie.setSignDateTime(null);
			cie.setSupervisionState(SupervisionStateEnum.ALREADY_SUPERVISE);
			cie.setRedeemState(Boolean.FALSE);
			cie.setDetainedState(Boolean.FALSE);
			cie.setBadassetsState(BadassetsStateEnum.UNKNOWN);
			cie.setValueDate(ci.getValueDate());
			cie.setSettlementDate(ci.getSettlementDate());
			cie.setPickupableDate(ci.getPickupableDate());
			cie.setPunishDate(ci.getPunishDate());
			cie.setDistrainDate(ci.getDistrainDate());
			cie.setHandleDate(ci.getHandleDate());
			cie.setAdjustment(BigDecimal.ZERO);

			FinanceCreditContainerBulkstockEntity fccb = fccbs.get(fcc.getContainerId());
			FinanceBulkstockEntity financeBulkstock = bulkstocks.get(fccb.getBulkstockInfoId());
			currentReplenishFinanceAmount = currentReplenishFinanceAmount.add(financeBulkstock.getFinancePrice().multiply(fccb.getValuationQuantity()));
			if (i == fccs.size() - 1) {
				cie.setAdjustment(currentReplenishFinanceAmount);
			}
			containerInventoryService.createContainerInventory(cie);

			ContainerBulkstockEntity cbe = new ContainerBulkstockEntity();
			cbe.setTallyingId(null);
			cbe.setTransportNoticeId(null);
			cbe.setInventoryId(cie.getInventoryId());
			cbe.setFinanceId(finance.getFinanceId());
			cbe.setBulkstockId(financeBulkstock.getBulkstockId());
			cbe.setBulkstockCategoryId(fccb.getBulkstockCategoryId());
			cbe.setBulkstockInfoId(fccb.getBulkstockInfoId());
			cbe.setBulkstockName(fccb.getBulkstockName());
			cbe.setSpecification(fccb.getSpecification());
			cbe.setUnit(fccb.getUnit());
			cbe.setPlannedQuantity(fccb.getQuantity());
			cbe.setPlannedVolume(fccb.getVolume());
			cbe.setPlannedWeight(fccb.getWeight());
			cbe.setQuantity(fccb.getQuantity());
			cbe.setVolume(fccb.getVolume());
			cbe.setWeight(fccb.getWeight());
			cbe.setMeasurement(fccb.getMeasurement());
			cbe.setValuationQuantity(fccb.getValuationQuantity());
			cbe.setTrayNumber(fccb.getTrayNumber());
			cbe.setBulkstockPrice(financeBulkstock.getBulkstockPrice());
			cbe.setEvaluatePrice(financeBulkstock.getEvaluatePrice());
			cbe.setFinancePrice(financeBulkstock.getFinancePrice());
			cbe.setAbnormal(Boolean.TRUE);
			cbe.setAbnormalComment(null);
			cbe.setFilesUuid(null);
			cbe.setEnabled(Boolean.TRUE);
			cbe.setCreateDateTime(DateUtil.now());
			cbe.setUpdateDateTime(DateUtil.now());
			containerBulkstockService.createContainerBulkstock(cbe);
		}

		// 添加箱量
		FinanceContainerEntity financeContainer = financeContainerService.inquireFinanceContainer(credit.getFinanceId());
		financeContainer.setCaseQuantity(financeContainer.getCaseQuantity() + fccs.size());
		financeContainerService.renovateFinanceContainer(financeContainer);
	}

	@Override
	public InterestEstimate interestEstimationFinanceInventory(Long financeId, Long[] inventoryIds, String cutoffDate) {
		if (inventoryIds == null || inventoryIds.length <= 0) {
			throw new BusinessException("货箱不允许为空");
		}
		PickupApplicationEntity pickup = new PickupApplicationEntity();
		pickup.setDeliveryDate(DateUtil.parseDateInt(cutoffDate));
		FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(financeId);
		FinanceProductEntity product = financeProductService.inquireFinanceProduct(finance.getProductId());
		List<ContainerInventoryEntity> inventories = containerInventoryService.inquireContainerInventoryList(inventoryIds);
		QuarterSettlementEntity settlement = null;
		if (LoanMethodEnum.FIXED_LOAN == product.getLoanMethod()) {
			settlement = FinanceLoanCastor.fromInterestSettlement(finance, inventories, product.getQuantitySettlement(), pickup, false);
		} else {
			settlement = FinanceLoanCastor.fromInterestSettlement(finance, inventories, null, pickup, false);
		}
		InterestEstimate interestEstimate = new InterestEstimate();
		interestEstimate.setInterest(settlement.getSettlementAmount());
		interestEstimate.setInterestOrigin(settlement.getSettlementAmountOrigin());
		interestEstimate.setPrincipal(settlement.getFinanceAmount());
		interestEstimate.setSummation(interestEstimate.getPrincipal().add(interestEstimate.getInterest()));
		return interestEstimate;
	}
	
	@Override
	public InterestEstimate interestEstimationFinanceInventory1(Long financeId, Long[] inventoryIds, String cutoffDate) {
		if (inventoryIds == null || inventoryIds.length <= 0) {
			throw new BusinessException("货箱不允许为空");
		}
		PickupApplicationEntity pickup = new PickupApplicationEntity();
		pickup.setDeliveryDate(DateUtil.parseDateInt(cutoffDate));
		FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(financeId);
		List<ContainerInventoryEntity> inventories = containerInventoryService.inquireContainerInventoryList(inventoryIds);
		
		QuarterSettlementEntity settlement = null;
		settlement = FinanceLoanCastor.fromInterestSettlement1(finance, inventories, null, pickup, false);
		InterestEstimate interestEstimate = new InterestEstimate();
		
		if(settlement!=null){
			interestEstimate.setInterest(settlement.getSettlementAmount());
			interestEstimate.setInterestOrigin(settlement.getSettlementAmountOrigin());
			interestEstimate.setPrincipal(settlement.getFinanceAmount());
			interestEstimate.setSummation(interestEstimate.getPrincipal()!=null?interestEstimate.getPrincipal().add(interestEstimate.getInterest()):interestEstimate.getInterest());
			//换箱费
			if (inventories.size() > 0) {
				if (PickupMethodEnum.EXCHANGE_CONTAINER == pickup.getPickupMethod()) {
					String em = systemParamService.inquireSytemParamDetailByName("换箱费");
					if (StringUtil.isNotBlank(em)) {
						interestEstimate.setExchangeExpense((new BigDecimal(em)).multiply(new BigDecimal(inventoryIds.length)));
					}
				}
			}
		}
		return interestEstimate;
	}

	@Override
	public String createInterestSettlement(Long financeId, Long[] inventoryId, Integer days) {
		FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(financeId);
		List<ContainerInventoryEntity> inventories = containerInventoryService.inquireContainerInventoryList(inventoryId);
		QuarterSettlementEntity entity = FinanceLoanCastor.fromInterestSettlement(finance, inventories, days, null, false);
		Long quarterSettlementId = quarterSettlementService.createQuarterSettlement(entity);
		for (QuarterSettlementContainerEntity qsc : entity.getContainers()) {
			qsc.setQuarterSettlementId(quarterSettlementId);
			quarterSettlementContainerService.createQuarterSettlementContainer(qsc);

			ContainerInventoryEntity inventory = qsc.getContainerInventory();
			containerInventoryService.renovateContainerInventory(inventory);
		}

		// 生成利息待收单
		FinanceMoneyStatementEntity moneyEntity = FinanceLoanCastor.fromInterestSettlement(entity);
		financeMoneyStatementService.createFinanceMoneyStatement(moneyEntity);
		return quarterSettlementId.toString();
	}

	@Override
	public PageList<QuarterSettlementLineInfo> inquiryInterestSettlement(Long financeId, PageCriteria page) {
		PageList<QuarterSettlementEntity> pageList = quarterSettlementService.inquiryInterestSettlement(financeId, page);
		PageList<QuarterSettlementLineInfo> infoList = new PageList<QuarterSettlementLineInfo>(page, pageList.getTotalRecordCount());
		for (QuarterSettlementEntity entity : pageList) {
			QuarterSettlementLineInfo info = FinanceLoanCastor.toSettlementLineInfo(entity);
			infoList.add(info);
		}
		return infoList;
	}

	@Override
	public QuarterSettlementLineInfo inquiryInterestSettlementDetail(Long quarterSettlementId) {
		QuarterSettlementEntity entity = quarterSettlementService.inquiryInterestSettlementDetail(quarterSettlementId);
		QuarterSettlementLineInfo info = FinanceLoanCastor.toSettlementLineInfo(entity);
		return info;
	}
	

	@Override
	public BigDecimal inquiryFinanceInterest(Long financeId, BigDecimal bulkstockAmount, Date interestDate) {
		Integer interestD = Integer.valueOf(systemParamActionApi.inquireSystemParamByName("结息日"));
//		return BigDecimal.ZERO;
		FinanceProductInnerEntity fpe = financeProductInnerService.inquireFinanceProductInner(financeId, null);
		List<FinanceProductInterestItemEntity> fpiies = financeProductInterestItemService.inquireFinanceProductInterestItemList(fpe.getFinanceProductId());
		List<LoanNoticeEntity> ls = loanNoticeService.inquireLoanNoticeList(financeId);
		Date start = DateUtils.now();
		for(LoanNoticeEntity lss:ls){
			if(lss.getLoanDate()!=null){
				start = DateUtils.fromDateInt(lss.getLoanDate());
			}
		}
		Integer days = DateUtils.daysBetween(start, interestDate) + 1;
		
		if (days == 1) {
			return BigDecimal.ZERO;
		}
		
		BigDecimal interest = BigDecimal.ZERO;
		for (FinanceProductInterestItemEntity fppie : fpiies) {
			if (days >= fppie.getStartDay() && days < fppie.getEndDay()) {
				if (fppie.getBillingMethod() == BillingMethodEnum.EXPENSE) {
					if (start.getDate() < interestD) {
						Date d = start;
						d.setDate(20);
						Integer da = DateUtils.daysBetween(start, d) + 1;
						interest = interest.add(((new BigDecimal(fppie.getEndDay()-fppie.getStartDay()+1-da)).multiply(fppie.getAmout().divide(FinanceConstant.HUNDRED, BigDecimal.ROUND_HALF_UP))).multiply(bulkstockAmount));
					} else {
						interest = interest.add(((new BigDecimal(fppie.getEndDay()-fppie.getStartDay()+1)).multiply(fppie.getAmout().divide(FinanceConstant.HUNDRED, BigDecimal.ROUND_HALF_UP))).multiply(bulkstockAmount));
					}
				} else {
					interest = interest.add(((new BigDecimal(days-fppie.getStartDay()+1)).multiply(fppie.getAmout().divide(FinanceConstant.HUNDRED, BigDecimal.ROUND_HALF_UP))).multiply(bulkstockAmount));
				}
			}
			if (days >= fppie.getEndDay()) {
				interest = interest.add(((new BigDecimal(fppie.getEndDay()-fppie.getStartDay()+1)).multiply(fppie.getAmout().divide(FinanceConstant.HUNDRED, BigDecimal.ROUND_HALF_UP))).multiply(bulkstockAmount));
			}
		}
		
		return interest;
	}

	// ===============================================================================================================================================================================//
	@Transactional
	@Override
	public String createInterestDelayApplication(Long financeId, Integer delayLimitTime, Integer applicantReson, String remark) {
		InterestDelayApplicationEntity entity = new InterestDelayApplicationEntity();
		entity.setApplicant(FinanceSessionContext.getAccountFullName());
		entity.setApplicantId(FinanceSessionContext.getAccountId());
		entity.setDelayLimitTime(delayLimitTime);
		entity.setApplicantReson(applicantReson);
		entity.setEnterpriseId(FinanceSessionContext.getEnterpriseId());
		entity.setEnterpriseName(FinanceSessionContext.getEnterpriseName());
		entity.setFinanceId(financeId);
		FinanceApplicationEntity financeEntity = financeApplicationService.inquireFinanceApplicationEntity(financeId);
		entity.setFinanceNumber(financeEntity.getFinanceNumber());
		entity.setRemark(remark);
		entity.setApplicantDatetime(DateUtil.now());
		entity.setInterestDelayDateTime(DateUtil.now());
		return interestDelayApplicationService.createInterestDelayApplication(entity).toString();
	}

	@Transactional
	@Override
	public void updateInterestDelayApplication(Long interestDelayId, Integer delayLimitTime) {
		InterestDelayApplicationEntity entity = interestDelayApplicationService.inquireInterestDelayApplicationDetail(interestDelayId);
		entity.setApplicant(FinanceSessionContext.getAccountFullName());
		entity.setApplicantId(FinanceSessionContext.getAccountId());
		entity.setDelayLimitTime(delayLimitTime);
		interestDelayApplicationService.updateInterestDelayApplication(entity);
	}

	@Transactional
	@Override
	public void cancelInterestDelayApplication(Long interestDelayId) {
		InterestDelayApplicationEntity entity = interestDelayApplicationService.inquireInterestDelayApplicationDetail(interestDelayId);
		entity.setApplicationState(ApplicationSimpleStateEnum.CANCEL);
		interestDelayApplicationService.updateInterestDelayApplication(entity);
	}

	@Transactional
	@Override
	public void consentInterestDelayApplication(Long interestDelayId, String auditRemark) {
		InterestDelayApplicationEntity entity = interestDelayApplicationService.inquireInterestDelayApplicationDetail(interestDelayId);
		entity.setApplicationState(ApplicationSimpleStateEnum.AGREE);
		entity.setAuditDateTime(DateUtil.now());
		entity.setAuditor(FinanceSessionContext.getAccountFullName());
		entity.setAuditorId(FinanceSessionContext.getAccountId());
		entity.setAuditRemark(auditRemark);
		entity.setInterestDelayDateTime(null);
		// 正常计息的货物利息日期顺延
		Date minValueDate = DateUtils.addDateField(new Date(), Calendar.DATE, -1);
		List<ContainerInventoryEntity> bulkstockInventoryList = containerInventoryService.inquireContainerInventoryList(entity.getFinanceId(), minValueDate);
		for (ContainerInventoryEntity inventoryEntity : bulkstockInventoryList) {
			inventoryEntity.setPunishDate(DateUtils.addDateField(inventoryEntity.getPunishDate(), Calendar.DATE, entity.getDelayLimitTime()));
			inventoryEntity.setDistrainDate(DateUtils.addDateField(inventoryEntity.getDistrainDate(), Calendar.DATE, entity.getDelayLimitTime()));
			inventoryEntity.setHandleDate(DateUtils.addDateField(inventoryEntity.getHandleDate(), Calendar.DATE, entity.getDelayLimitTime()));
			containerInventoryService.renovateContainerInventory(inventoryEntity);
		}
		interestDelayApplicationService.updateInterestDelayApplication(entity);
	}

	@Transactional
	@Override
	public void opposeInterestDelayApplication(Long interestDelayId, Integer disagreeReson, String auditRemark) {
		InterestDelayApplicationEntity entity = interestDelayApplicationService.inquireInterestDelayApplicationDetail(interestDelayId);
		entity.setApplicationState(ApplicationSimpleStateEnum.DISAGREE);
		entity.setAuditDateTime(DateUtil.now());
		entity.setDisagreeReson(disagreeReson);
		entity.setAuditor(FinanceSessionContext.getAccountFullName());
		entity.setAuditorId(FinanceSessionContext.getAccountId());
		entity.setAuditRemark(auditRemark);
		interestDelayApplicationService.updateInterestDelayApplication(entity);
	}

	@Override
	public InterestDelayDetail inquireInterestDelayApplicationDetail(Long interestDelayId) {
		InterestDelayApplicationEntity entity = interestDelayApplicationService.inquireInterestDelayApplicationDetail(interestDelayId);
		return FinanceLoanCastor.toInterestDelayDetail(entity);
	}

	@Override
	public PageList<InterestDelayLineInfo> inquireInterestDelayApplicationPageList(Long[] interestDelayIds, Long financeId, String financeNumber, Long enterpriseId, String enterpriseName, Integer applicationState, PageCriteria page) {
		if (FinanceSessionContext.isEnterprise()) {
			enterpriseId = FinanceSessionContext.getEnterpriseId();
		}
		ApplicationSimpleStateEnum _enum = null;
		if (applicationState != null) {
			_enum = ApplicationSimpleStateEnum.valueOf(applicationState);
		}
		PageList<InterestDelayApplicationEntity> pageList = interestDelayApplicationService.inquireInterestDelayApplicationPageList(interestDelayIds, financeId, financeNumber, enterpriseId, enterpriseName, _enum, page);
		PageList<InterestDelayLineInfo> resultList = new PageList<>(page, pageList.getTotalRecordCount());
		for (InterestDelayApplicationEntity entity : pageList) {
			resultList.add(FinanceLoanCastor.toInterestDelayLineInfo(entity));
		}
		return resultList;
	}

	// =================================================================================================//
	@Transactional
	@Override
	public String createLoanNotice(LoanNoticeParams params) {
		PermissionActionsApi permissionAction = ComponentFactory.loadClass(PermissionActionsApi.class);
		List<RoleListDto> rl = permissionAction.inquireAccountRoleList(FinanceSessionContext.getAccountId());
		StringBuffer sb = new StringBuffer();
		for (RoleListDto rlt : rl) {
			sb.append(rlt.getRoleName()).append(",");
		}
		sb.deleteCharAt(sb.length() - 1);
		FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(params.getFinanceId());
		if (finance.getTotalLoanAmount().compareTo(finance.getFinanceAmount().subtract(params.getLoanAmount())) > 0) {
			throw new BusinessException("放款金额超过融资金额");
		}
		BigDecimal unConsentLoanAmount = loanNoticeService.inquireFinanceUnConsentLoanAmount(finance);
		if (finance.getTotalLoanAmount().compareTo(finance.getFinanceAmount().subtract(params.getLoanAmount().subtract(unConsentLoanAmount))) > 0) {
			throw new BusinessException("放款金额超过融资金额,待确认金额【" + unConsentLoanAmount + "】");
		}

		FinanceAuditEntity audit = financeAuditService.inquireLatestFinanceAudit(finance.getFinanceId());
		if (finance.getBail().compareTo(BigDecimal.ZERO) > 0) {
			String[] statementSource = new String[] { "FINANCE_AUDIT", "BAIL_ADDITION" };
			Long financeId = audit.getFinanceId();
			FinanceMoneyStatementEntity statement = financeMoneyStatementService.inquireFinanceMoneyStatementDetail(statementSource, financeId);
			if (statement != null && !statement.getReceiptVerifiState()) {
				throw new BusinessException("保证金未核销,不允许放款");
			}
		}

		LoanNoticeEntity loanNotice = FinanceLoanCastor.fromLoanNotice(params, finance);
		loanNotice.setLoanAuditCreateTime(DateUtil.now());
		FinanceAuditLogEntity fale = new FinanceAuditLogEntity(DateUtil.now(), sb.toString(), 1L, FinanceSessionContext.getAccountFullName() + "发起放款申请", loanNotice.getLoanNoticeId(), 2L,FinanceSessionContext.getAccountId());
		financeAuditLogService.createFinanceAuditLogEntity(fale);
		
		loanNotice.setFinalState(ApiFinanceStateEnum.ZJ.getCode());
		
		loanNotice.setCallback(Boolean.FALSE);
		
		Long loanNoticeId = loanNoticeService.createLoanNotice(loanNotice);

		List<ContainerInventoryEntity> containerInventoryList = containerInventoryService.inquireContainerInventoryList(params.getInventoryId());
		for (ContainerInventoryEntity cie : containerInventoryList) {
			cie.setLoanNoticeId(loanNoticeId);
			containerInventoryService.renovateContainerInventory(cie);
			
			FinanceContainerLogEntity fcle = new FinanceContainerLogEntity();
			fcle.setInventoryId(cie.getInventoryId());
			fcle.setOperator(FinanceSessionContext.getAccountFullName());
			fcle.setRemark("放款申请");
			financeContainerLogService.createFinanceContainerLog(fcle);
		}

		finance.setLoanApplicationCreateDatetime(null);
		financeApplicationService.renovateFinanceApplication(finance);

		//消息推送-资金审核
		SendLetterMessage.sendLetterMessage("loanNoticeFinancialAudit_1", String.format(tmp, finance.getEnterpriseName(), finance.getFinanceNumber(), "资金审核"));
		return loanNoticeId.toString();
	}

	@Transactional
	@Override
	public void updateLoanNotice(LoanNoticeUpdateParams params) {
		LoanNoticeEntity persist = loanNoticeService.inquireLoanNoticeEntity(params.getLoanNoticeId());
		if (ApplicantLoanStateEnum.WAIT_AUDIT != persist.getLoanState()) {
			throw new BusinessException("放款单已经审核确认,不允许修改!");
		}
		FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(persist.getFinanceId());
		if (finance.getTotalLoanAmount().compareTo(finance.getFinanceAmount().subtract(params.getLoanAmount())) > 0) {
			throw new BusinessException("放款金额超过融资金额");
		}
		BigDecimal unConsentLoanAmount = loanNoticeService.inquireFinanceUnConsentLoanAmount(finance);
		if (finance.getTotalLoanAmount().compareTo(finance.getFinanceAmount().subtract(params.getLoanAmount().subtract(unConsentLoanAmount))) > 0) {
			throw new BusinessException("放款金额超过融资金额,待确认金额【" + unConsentLoanAmount + "】");
		}

		LoanNoticeEntity loanNotice = FinanceLoanCastor.fromLoanNotice(params, finance);
		loanNotice.setLoanNoticeId(params.getLoanNoticeId());
		loanNoticeService.updateLoanNotice(loanNotice);

		List<ContainerInventoryEntity> inventoryList = containerInventoryService.inquireLoanNoticeContainerInventoryList(params.getLoanNoticeId());
		Set<Long> inventoryIds = CollectionUtils.convertSet(params.getInventoryId());
		for (ContainerInventoryEntity cie : inventoryList) {
			if (inventoryIds.contains(cie.getInventoryId())) {
				inventoryIds.remove(cie.getInventoryId());
			} else {
				cie.setLoanNoticeId(null);
				containerInventoryService.renovateContainerInventory(cie);
			}
		}
		for (Long inventoryId : inventoryIds) {
			ContainerInventoryEntity cie = containerInventoryService.inquireContainerInventory(inventoryId);
			cie.setLoanNoticeId(params.getLoanNoticeId());
			containerInventoryService.renovateContainerInventory(cie);
		}
	}

	@Transactional
	@Override
	public void consentLoanNotice(LoanNoticeConsentParams params) {
		LoanNoticeEntity loanNotice = loanNoticeService.inquireLoanNoticeEntity(params.getLoanNoticeId());
		BeanUtils.copyProperties(params, loanNotice);
		loanNotice.setLoanState(ApplicantLoanStateEnum.AGREE);
		loanNotice.setAuditDateTime(DateUtil.now());
		loanNotice.setAuditor(FinanceSessionContext.getAccountFullName());
		loanNotice.setAuditorId(FinanceSessionContext.getAccountId());
		loanNotice.setLoanAuditCreateTime(null);
		loanNoticeService.renovateLoanNotice(loanNotice);
		// 项目状态更新 核销以后才改变放款金额
		FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(loanNotice.getFinanceId());
//		finance.setTotalLoanAmount(finance.getTotalLoanAmount().add(loanNotice.getLoanAmount())); // 设置放款金额
//		核销以后才更改融资状态
//		finance.setFinanceState(FinanceStateEnum.LOANED);
		if (finance.getTotalLoanAmount().compareTo(finance.getFinanceAmount()) > 0) {
			throw new BusinessException("放款金额超过融资金额");
		}

		finance.setTransportNoticeCreateDatetime(DateUtil.now());
		if ("1".equals(finance.getIsSign())) {
			finance.setFinanceConstractState(FinanceConstractStateEnum.WAIT_PLATFORM_SIGN);
		} else {
			finance.setFinanceState(FinanceStateEnum.SUPPLEMENT_CONTRACT);
		}
		financeApplicationService.renovateFinanceApplication(finance);

		Date valueDate = DateUtil.thatDay(new Date()); // 当天开始计息
		Date settlementDate = DateUtils.addDateField(valueDate, Calendar.DATE, -1); // 已结算日期
		// 计算货箱的 可提日期点/罚息日期点/赎货日期点/处置日期点
		Integer advanceTimeLimit = finance.getAdvanceTimeLimit(); // 提前违约期限
		Date pickupableDate = DateUtils.addDateField(valueDate, Calendar.DATE, advanceTimeLimit == null? 0 : advanceTimeLimit); // 可提开始日期-当天可提

		Integer loanTimeLimit = finance.getLoanTimeLimit(); // 借款期限
		Date punishDate = DateUtils.addDateField(valueDate, Calendar.DATE, loanTimeLimit); // 罚息开始日期-当天开始罚息

//		Integer punishTimeLimit = finance.getPunishTimeLimit(); // 罚息期限
//		Date distrainDate = DateUtils.addDateField(punishDate, Calendar.DATE, punishTimeLimit); // 赎货开始日期-当天开始处置
		Date distrainDate = DateUtils.addDateField(punishDate, Calendar.DATE, 0);

//		Integer distrainTimeLimit = finance.getDistrainTimeLimit(); // 赎货期限
//		Date handleDate = DateUtils.addDateField(distrainDate, Calendar.DATE, distrainTimeLimit); // 处置开始日期-当天开始处置
		Date handleDate = DateUtils.addDateField(distrainDate, Calendar.DATE, 0);
		List<ContainerInventoryEntity> inventories = containerInventoryService.inquireLoanNoticeContainerInventoryList(loanNotice.getLoanNoticeId());
		for (ContainerInventoryEntity cie : inventories) {
			cie.setValueDate(valueDate);
			cie.setSettlementDate(settlementDate);
			cie.setPickupableDate(pickupableDate);
			cie.setPunishDate(punishDate);
			cie.setDistrainDate(distrainDate);
			cie.setHandleDate(handleDate);
			//运费保理不需要通知运输
			if (ProductTypeEnum.FREIGHT_FACTORING == finance.getProductType()) {
				cie.setSupervisionState(SupervisionStateEnum.ALREADY_SUPERVISE);
				cie.setSignState(Boolean.TRUE);
				cie.setAbnormal(Boolean.TRUE);
			}
			containerInventoryService.renovateContainerInventory(cie);
			
			FinanceContainerLogEntity fcle = new FinanceContainerLogEntity();
			fcle.setInventoryId(cie.getInventoryId());
			fcle.setOperator(FinanceSessionContext.getAccountFullName());
			fcle.setRemark("放款审批通过");
			financeContainerLogService.createFinanceContainerLog(fcle);
		}

		// 项目动态
		FinanceProcessEntity processEntity = FinanceProcessCastor.fromFinanceLoanProcess(loanNotice, null);
		if (!LongUtils.isPrimaryKey(processEntity.getProcessId())) {
			financeProcessService.createFinanceProcess(processEntity);
		} else {
			financeProcessService.renovateFinanceProcess(processEntity);
		}
		processEntity.getCurrentDetail().setProcessId(processEntity.getProcessId());
		financeProcessDetailService.createFinanceProcessDetail(processEntity.getCurrentDetail());
		// 生成付款单
		FinanceMoneyStatementEntity moneyEntity = FinanceLoanCastor.fromCommidityLoanNotice(loanNotice);
		financeMoneyStatementService.createFinanceMoneyStatement(moneyEntity);
		
		//生成收款单-运费保理 自动
		if (ProductTypeEnum.FREIGHT_FACTORING == finance.getProductType()) {
			//货物金额
			LogisticsCompanyEntity lce = logisticsCompanyService.inquireLogisticsCompanyByCompanyName(finance.getDeliver());
			PickupApplicationEntity pickup = new PickupApplicationEntity();
			pickup.setFinanceId(finance.getFinanceId());
			pickup.setFinanceNumber(finance.getFinanceNumber());
			pickup.setEnterpriseName(lce.getCompanyName());
			pickup.setFinanceValuation(loanNotice.getLoanAmount());
			pickup.setEnterpriseId(lce.getCompanyId());
			
			pickup.setPickupMethod(PickupMethodEnum.CASH_DELIVERY);
			pickup.setDeliveryMethod(DeliveryMethodEnum.ARRIVAL_DOOL);
			pickup.setDeliveryDate(DateUtils.parseDateInt(DateUtils.now()));
			
			pickup.setApplicant(FinanceSessionContext.getAccountFullName());
			pickup.setApplicantId(FinanceSessionContext.getAccountId());
			pickup.setApplicantDateTime(DateUtil.now());
			pickup.setApplicationState(ApplicationStateEnum.AGREE);
			pickup.setLoanNoticeId(loanNotice.getLoanNoticeId());
			pickup.setPickupType(PickupTypeEnum.NORMAL);
			pickup.setRemark("运费保理");
			pickupApplicationService.createPickupApplicationEntity(pickup);
			FinanceMoneyStatementEntity fme = FinanceLoanCastor.fromPickupApplication(pickup);
			fme.setDisbursementType(OperatorRoleEnum.LOGISTICS.ordinal());
			financeMoneyStatementService.createFinanceMoneyStatement(fme);
			pickup.setFinanceValuation(fme.getAmount());
			pickup.setCeoAudit("系统自动审批通过");
			pickup.setCeoAuditDate(DateUtil.nowDate());
			pickup.setCeoAuditor("指尖金融系统");
			pickup.setCeoAuditorId(0L);
			pickup.setCeoAuditState(Boolean.TRUE);
			pickup.setCeoAuditSubmitState(Boolean.TRUE);
			
			pickup.setRiskAudit("系统自动审批通过");
			pickup.setRiskAuditDate(DateUtil.nowDate());
			pickup.setRiskAuditor("指尖金融系统");
			pickup.setRiskAuditorId(0L);
			pickup.setRiskAuditState(Boolean.TRUE);
			pickup.setRiskAuditSubmitState(Boolean.TRUE);
			
			pickup.setRiskMemberAudit("系统自动审批通过");
			pickup.setRiskMemberAuditDate(DateUtil.nowDate());
			pickup.setRiskMemberAuditor("指尖金融系统");
			pickup.setRiskMemberAuditorId(0L);
			pickup.setRiskMemberAuditState(Boolean.TRUE);
			pickup.setRiskMemberAuditSubmitState(Boolean.TRUE);
			
			pickup.setBusinessAudit("系统自动审批通过");
			pickup.setBusinessAuditDate(DateUtil.nowDate());
			pickup.setBusinessAuditor("指尖金融系统");
			pickup.setBusinessAuditorId(0L);
			pickup.setBusinessAuditState(Boolean.TRUE);
			pickup.setBusinessAuditSubmitState(Boolean.TRUE);
			
			pickup.setFinancialAudit("系统自动审批通过");
			pickup.setFinancialAuditDate(DateUtil.nowDate());
			pickup.setFinancialAuditor("指尖金融系统");
			pickup.setFinancialAuditorId(0L);
			pickup.setFinancialAuditState(Boolean.TRUE);
			pickup.setFinancialAuditSubmitState(Boolean.TRUE);
			
			pickup.setOperationAudit("系统自动审批通过");
			pickup.setOperationAuditDate(DateUtil.nowDate());
			pickup.setOperationAuditor("指尖金融系统");
			pickup.setOperationAuditorId(0L);
			pickup.setOperationAuditState(Boolean.TRUE);
			pickup.setOperationAuditSubmitState(Boolean.TRUE);
			
			pickup.setFinanceValuation(fme.getAmount());
			pickup.setCeoAudit("系统自动审批通过");
			pickup.setCeoAuditDate(DateUtil.nowDate());
			pickup.setCeoAuditor("指尖金融系统");
			pickup.setCeoAuditorId(0L);
			pickup.setCeoAuditState(Boolean.TRUE);
			pickup.setCeoAuditSubmitState(Boolean.TRUE);
			
			//利息
			PickupApplicationEntity pickup1 = new PickupApplicationEntity();
			pickup1.setPickupId(pickup.getPickupId());
			pickup1.setFinanceId(finance.getFinanceId());
			pickup1.setFinanceNumber(finance.getFinanceNumber());
			pickup1.setEnterpriseName(finance.getEnterpriseName());
//			System.out.println(loanNotice.getLoanAmount().multiply((finance.getAuditInterest()).divide(new BigDecimal(100*360), 8, BigDecimal.ROUND_HALF_UP)).multiply(new BigDecimal(finance.getLoanTimeLimit())));
			BigDecimal interest = loanNotice.getLoanAmount().multiply((finance.getAuditInterest()).divide(new BigDecimal(100*360), 8, BigDecimal.ROUND_HALF_UP)).multiply(new BigDecimal(finance.getLoanTimeLimit()));
			interest = new BigDecimal(new DecimalFormat("#.00").format(interest));
			pickup1.setBulkstockInterest(interest);
			pickup1.setEnterpriseId(finance.getEnterpriseId());
			FinanceMoneyStatementEntity fme1 = FinanceLoanCastor.fromPickupApplicationInterest(pickup1);
			fme1.setDisbursementType(OperatorRoleEnum.ENTERPRISE.ordinal());
			financeMoneyStatementService.createFinanceMoneyStatement(fme1);
			pickup.setBulkstockInterest(fme1.getAmount());
			pickup.setAllowValuation(fme.getAmount().add(fme1.getAmount()));
			pickup.setEstimateAmount(fme.getAmount().add(fme1.getAmount()));
			
			pickupApplicationService.updatePickupApplication(pickup);
			
			// 生成提货单货物信息
			Collection<PickupBulkstockEntity> bulkstockEntities = BulkstockPledgeCastor.fromPickupInventory(inventories);
			for (PickupBulkstockEntity pce : bulkstockEntities) {
				pickupBulkstockService.createPickupBulkstock(pce);
			}
			
			for (ContainerInventoryEntity cie : inventories) {
				cie.setPickupId(pickup.getPickupId());
				cie.setPickupModel(PickupModelEnum.USER_ASSIGN);
				containerInventoryService.renovateContainerInventory(cie);
				
				PickupInventoryEntity pie = new PickupInventoryEntity();
				pie.setInventoryId(cie.getInventoryId());
				pie.setPickupId(pickup.getPickupId());
				pie.setInterest(BigDecimal.ZERO);
				pickupInventoryService.createPickupInventory(pie);
			}
		}
	}
	
	@Override
	@Transactional
	public void opposeLoanNotice(Long loanNoticeId) {
		LoanNoticeEntity loanNotice = loanNoticeService.inquireLoanNoticeEntity(loanNoticeId);
		loanNotice.setLoanState(ApplicantLoanStateEnum.OPPOSE);
		loanNotice.setAuditDateTime(DateUtil.now());
		loanNotice.setAuditor(FinanceSessionContext.getAccountFullName());
		loanNotice.setAuditorId(FinanceSessionContext.getAccountId());
		loanNoticeService.renovateLoanNotice(loanNotice);
		
		//风控审批拒绝，删除箱号信息（融资产品状态为3,5,6）和箱号货物信息
		//1 判断融资产品状态
		FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(loanNotice.getFinanceId());
		int ordinal = finance.getProductType().ordinal();
		if(ordinal == 3 || ordinal == 5 || ordinal == 6) {
			List<FinanceBulkstockEntity> fbes = financeBulkstockService.inquireFinanceBulkstockList(finance.getFinanceId());
			for (FinanceBulkstockEntity fbe : fbes) {
				fbe.setRecieve(BigDecimal.ZERO);
				financeBulkstockService.updateFinanceBulkstockEntity(fbe);
			}
			List<ContainerInventoryEntity> inventoryList = containerInventoryService.inquireEffectiveContainerInventoryList(finance.getFinanceId());
			for (ContainerInventoryEntity containerInventoryEntity : inventoryList) {
				Long inventoryId = containerInventoryEntity.getInventoryId();
				containerInventoryService.deleteContainerInventory(inventoryId);
				//删除货箱货物信息
				List<ContainerBulkstockEntity> containerBulkstockList = containerBulkstockService.inquireContainerBulkstockList(inventoryId);
				for (ContainerBulkstockEntity containerBulkstockEntity : containerBulkstockList) {
					containerBulkstockService.deleteContainerBulkstock(containerBulkstockEntity.getContainerBulkstockId());
				}
			}
		} else {
			List<ContainerInventoryEntity> containerInventoryList = containerInventoryService.inquireLoanNoticeContainerInventoryList(loanNotice.getLoanNoticeId());
			for (ContainerInventoryEntity cie : containerInventoryList) {
				cie.setLoanNoticeId(null);
				containerInventoryService.renovateContainerInventory(cie);
			}
		}
		
		List<FinanceFilesInfoEntity> ffies = financeFilesInfoService.inquireFinanceFilesInfoList(loanNotice.getFinanceId(), null);
		for (FinanceFilesInfoEntity ffie : ffies) {
			for (String fuid : ffie.getFilesUuid().split(",")) {
				SignFileInfoEntity sfie = signFileInfoService.inquireSignFileInfo(fuid);
				if (StringUtil.isBlank(sfie.getFilesSign()) || "0".equals(sfie.getFilesSign())) {
					sfie.setFileSignState(FileSignStateEnum.UNKNOWN);
				} else {
					sfie.setFileSignState(FileSignStateEnum.CLIENT_SIGN);
				}
				signFileInfoService.updateSignFileInfo(sfie);
			}
		}
		
		//消息推送-商务部
		SendLetterMessage.sendLetterMessage("businessAudit_1", String.format(tmp, finance.getEnterpriseName(), finance.getFinanceNumber(), "商务审核"));
	}

	@Override
	@Transactional
	public void saveLoanNoticeAudit(Integer auditType, String audit, Boolean auditState, Long loanNoticeId, Boolean autoNotice) {
		LoanNoticeEntity loanNotice = loanNoticeService.inquireLoanNoticeEntity(loanNoticeId);
		switch (auditType) {
		case 1:
			if (loanNotice.getBusinessAuditSubmitState() != null && loanNotice.getBusinessAuditSubmitState()) {
				throw new BusinessException("已提交的审核意见不能再修改");
			}
			loanNotice.setBusinessAudit(audit);
			loanNotice.setBusinessAuditDate(DateUtil.now());
			loanNotice.setBusinessAuditState(auditState);
			loanNotice.setBusinessAuditor(FinanceSessionContext.getAccountFullName());
			break;
		case 2:
			if (loanNotice.getOperationAuditSubmitState() != null && loanNotice.getOperationAuditSubmitState()) {
				throw new BusinessException("已提交的审核意见不能再修改");
			}
			loanNotice.setOperationAudit(audit);
			loanNotice.setOperationAuditDate(DateUtil.now());
			loanNotice.setOperationAuditState(auditState);
			loanNotice.setOperationAuditor(FinanceSessionContext.getAccountFullName());
			break;
		case 3:
			if (loanNotice.getFinancialAuditSubmitState() != null && loanNotice.getFinancialAuditSubmitState()) {
				throw new BusinessException("已提交的审核意见不能再修改");
			}
			loanNotice.setFinancialAudit(audit);
			loanNotice.setFinancialAuditDate(DateUtil.now());
			loanNotice.setFinancialAuditState(auditState);
			loanNotice.setFinancialAuditor(FinanceSessionContext.getAccountFullName());
			loanNotice.setAutoNotice(autoNotice);
			break;
		case 4:
			if (loanNotice.getFinancialLeaderAuditSubmitState() != null && loanNotice.getFinancialLeaderAuditSubmitState()) {
				throw new BusinessException("已提交的审核意见不能再修改");
			}
			loanNotice.setFinancialLeaderAudit(audit);
			loanNotice.setFinancialLeaderAuditDate(DateUtil.now());
			loanNotice.setFinancialLeaderAuditState(auditState);
			loanNotice.setFinancialLeaderAuditor(FinanceSessionContext.getAccountFullName());
			break;
		case 5:
			if (loanNotice.getLeader2AuditSubmitState() != null && loanNotice.getLeader2AuditSubmitState()) {
				throw new BusinessException("已提交的审核意见不能再修改");
			}
			if (Boolean.FALSE == auditState && StringUtils.isBlank(audit)) {
				throw new BusinessException("请输入审批意见");
			}
			loanNotice.setLeader2Audit(audit);
			loanNotice.setLeader2AuditDate(DateUtil.now());
			loanNotice.setLeader2AuditState(auditState);
			loanNotice.setLeader2Auditor(FinanceSessionContext.getAccountFullName());
			break;
		case 6:
			if (loanNotice.getLeader1AuditSubmitState() != null && loanNotice.getLeader1AuditSubmitState()) {
				throw new BusinessException("已提交的审核意见不能再修改");
			}
			if (Boolean.FALSE == auditState && StringUtils.isBlank(audit)) {
				throw new BusinessException("请输入审批意见");
			}
			loanNotice.setLeader1Audit(audit);
			loanNotice.setLeader1AuditDate(DateUtil.now());
			loanNotice.setLeader1AuditState(auditState);
			loanNotice.setLeader1Auditor(FinanceSessionContext.getAccountFullName());
			break;
		case 7:
			if (loanNotice.getAuditSubmitState1() != null && loanNotice.getAuditSubmitState1()) {
				throw new BusinessException("已提交的审核意见不能再修改");
			}
			if (Boolean.FALSE == auditState && StringUtils.isBlank(audit)) {
				throw new BusinessException("请输入审批意见");
			}
			loanNotice.setAudit1(audit);
			loanNotice.setAuditDate1(DateUtil.now());
			loanNotice.setAuditState1(auditState);
			loanNotice.setAuditor1(FinanceSessionContext.getAccountFullName());
			break;
		case 8:
			if (loanNotice.getAuditSubmitState2() != null && loanNotice.getAuditSubmitState2()) {
				throw new BusinessException("已提交的审核意见不能再修改");
			}
			loanNotice.setAudit2(audit);
			loanNotice.setAuditDate2(DateUtil.now());
			loanNotice.setAuditState2(auditState);
			loanNotice.setAuditor2(FinanceSessionContext.getAccountFullName());
			break;
		default:
			break;
		}
		loanNoticeService.renovateLoanNotice(loanNotice);
	}
	
	@Override
	@Transactional
	public void submitLoanNoticeAudit(Integer auditType, String audit, Boolean auditState, Long loanNoticeId, Boolean autoNotice) {
		saveLoanNoticeAudit(auditType, audit, auditState, loanNoticeId, autoNotice);
		//财务-3
		//财务领导-4
		//副总经理-6
		//总经理-5
		//董事长-7
		PermissionActionsApi permissionAction = ComponentFactory.loadClass(PermissionActionsApi.class);
		List<RoleListDto> rl = permissionAction.inquireAccountRoleList(FinanceSessionContext.getAccountId());
		StringBuffer sb = new StringBuffer();
		for (RoleListDto rlt : rl) {
			sb.append(rlt.getRoleName()).append(",");
		}
		sb.deleteCharAt(sb.length() - 1);
		LoanNoticeEntity loanNotice = loanNoticeService.inquireLoanNoticeEntity(loanNoticeId);
		FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(loanNotice.getFinanceId());
		switch (auditType) {
		case 1:
			loanNotice.setBusinessAuditSubmitState(Boolean.TRUE);
			SendLetterMessage.sendLetterMessage("loanNoticeOperationAudit_1", String.format(tmp, finance.getEnterpriseName(), finance.getFinanceNumber(), "风控领导审核"));
			break;
		case 2:
			loanNotice.setOperationAuditSubmitState(Boolean.TRUE);
			if(Boolean.FALSE == loanNotice.getOperationAuditState()) {
				loanNotice.setOperationAuditSubmitState(Boolean.FALSE);
				loanNotice.setBusinessAuditSubmitState(Boolean.FALSE);
				loanNotice.setAuditSubmitState2(Boolean.FALSE);
				loanNotice.setAuditSubmitState1(Boolean.FALSE);
				SendLetterMessage.sendLetterMessage("loanNoticeAudit1_1", String.format(tmp, finance.getEnterpriseName(), finance.getFinanceNumber(), "运营审核"));
			} else {
				SendLetterMessage.sendLetterMessage("loanNoticeFinancialAudit_1", String.format(tmp, finance.getEnterpriseName(), finance.getFinanceNumber(), "资金审核"));
			}
			break;
		case 3:
			if (Boolean.TRUE == loanNotice.getFinancialAuditSubmitState()) {
				throw new BusinessException("已提交的审核意见不能再修改");
			}
			FinanceAuditLogEntity fale3 = new FinanceAuditLogEntity(DateUtil.now(), sb.toString(), loanNotice.getFinancialAuditState()?1L:0, "资金部:" + loanNotice.getFinancialAudit(), loanNotice.getLoanNoticeId(), 2L,FinanceSessionContext.getAccountId());
			financeAuditLogService.createFinanceAuditLogEntity(fale3);
			if (Boolean.FALSE == loanNotice.getFinancialAuditState()) {
				initLoanNotice(loanNotice);
			} else {
				//消息推送-资金领导
				SendLetterMessage.sendLetterMessage("loanNoticeFinancialLeaderAudit_1", String.format(tmp, finance.getEnterpriseName(), finance.getFinanceNumber(), "资金领导审核"));
				loanNotice.setFinalState(ApiFinanceStateEnum.ZJMANAGE.getCode());
				loanNotice.setFinancialAuditSubmitState(Boolean.TRUE);
			}
			break;
		case 4:
			if (Boolean.TRUE == loanNotice.getFinancialLeaderAuditSubmitState()) {
				throw new BusinessException("已提交的审核意见不能再修改");
			}
			FinanceAuditLogEntity fale4 = new FinanceAuditLogEntity(DateUtil.now(), sb.toString(), loanNotice.getFinancialLeaderAuditState()?1L:0, "资金领导:" + loanNotice.getFinancialLeaderAudit(), loanNotice.getLoanNoticeId(), 2L,FinanceSessionContext.getAccountId());
			financeAuditLogService.createFinanceAuditLogEntity(fale4);
			loanNotice.setFinalState(ApiFinanceStateEnum.FMANAGE.getCode());
			loanNotice.setFinancialLeaderAuditSubmitState(Boolean.TRUE);
			if (Boolean.FALSE == loanNotice.getFinancialLeaderAuditState()) {
				initLoanNotice(loanNotice);
			} else {
				SendLetterMessage.sendLetterMessage("loanNoticeLeader1Audit_1", String.format(tmp, finance.getEnterpriseName(), finance.getFinanceNumber(), "副总经理审核"));
			}
			break;
		case 5:
			if (Boolean.TRUE == loanNotice.getLeader2AuditSubmitState()) {
				throw new BusinessException("已提交的审核意见不能再修改");
			}
			FinanceAuditLogEntity fale5 = new FinanceAuditLogEntity(DateUtil.now(), sb.toString(), loanNotice.getLeader2AuditState()?1L:0, "总经理:" + loanNotice.getLeader2Audit(), loanNotice.getLoanNoticeId(), 2L,FinanceSessionContext.getAccountId());
			financeAuditLogService.createFinanceAuditLogEntity(fale5);
			loanNotice.setLeader2AuditSubmitState(Boolean.TRUE);
			loanNotice.setFinalState(ApiFinanceStateEnum.ZXMANAGE.getCode());
			if (Boolean.FALSE == loanNotice.getLeader2AuditState()) {
				initLoanNotice(loanNotice);
			} else {
				SendLetterMessage.sendLetterMessage("loanNoticeAudit1_1", String.format(tmp, finance.getEnterpriseName(), finance.getFinanceNumber(), "董事长"));
			}	
			break;
		case 6:
			if (Boolean.TRUE == loanNotice.getLeader1AuditSubmitState()) {
				throw new BusinessException("已提交的审核意见不能再修改");
			}
			FinanceAuditLogEntity fale6 = new FinanceAuditLogEntity(DateUtil.now(), sb.toString(), loanNotice.getLeader1AuditState()?1L:0, "副总经理:" + loanNotice.getLeader1Audit(), loanNotice.getLoanNoticeId(), 2L,FinanceSessionContext.getAccountId());
			financeAuditLogService.createFinanceAuditLogEntity(fale6);
			loanNotice.setLeader1AuditSubmitState(Boolean.TRUE);
//			loanNotice.setFinalState(ApiFinanceStateEnum.TMANAGE.getCode());
			loanNotice.setFinalState(ApiFinanceStateEnum.FINISHED.getCode());
			if (Boolean.FALSE == loanNotice.getLeader1AuditState()) {
				initLoanNotice(loanNotice);
			} else {
				LoanNoticeConsentParams params = new LoanNoticeConsentParams();
				params.setLoanNoticeId(loanNotice.getLoanNoticeId());
				params.setAuditRemark(loanNotice.getAuditRemark());
				params.setBeneficiaryCreditCard(loanNotice.getBeneficiaryCreditCard());
				params.setBeneficiaryBank(loanNotice.getBeneficiaryBank());
				params.setBeneficiaryName(loanNotice.getBeneficiaryName());
				params.setLoanNumber(loanNotice.getLoanNumber());
				params.setLoanCreditCard(loanNotice.getLoanCreditCard());
				params.setLoanDate(loanNotice.getLoanDate().toString());
				params.setLoanMethod(loanNotice.getLoanMethod().ordinal());
				consentLoanNotice(params);
				if (Boolean.TRUE == loanNotice.getAutoNotice()) {
					List<Long> inventoryIds = containerInventoryService.inquireLoanNoticeContainerInventoryIdList(loanNoticeId);
					RecieveNoticeEntity rne = recieveNoticeService.inquireRecieveNoticeList(finance.getFinanceId()).get(0);
					financeBulkstockNoticeActionApi.createTransportNotice(finance.getFinanceId(), finance.getFinanceNumber(), rne.getLogisticsCompanyId(), rne.getLogisticsCompanyName(), "运输通知", inventoryIds.toArray(new Long[inventoryIds.size()]));
				}
				List<FinanceBulkstockEntity> fbes = financeBulkstockService.inquireFinanceBulkstockList(loanNotice.getFinanceId());
				FinanceCompleteResultEntity fcre = new FinanceCompleteResultEntity(loanNotice.getLoanNoticeId(), fbes.get(0).getBulkstockName(), fbes.get(0).getQuantity(), fbes.get(0).getUnit(), ApiTypeEnum.FK.getCode(), loanNotice.getLoanNoticeNumber(), DateUtil.now(), loanNotice.getEnterpriseName(), finance.getProductName(), loanNotice.getLoanAmount());
				financeAuditLogService.createFinanceCompleteResultEntity(fcre);
				
//				SendLetterMessage.sendLetterMessage("loanNoticeLeader2Audit_1", String.format(tmp, finance.getEnterpriseName(), finance.getFinanceNumber(), "总经理审核"));
			}
			break;
		case 7:
			if (Boolean.TRUE == loanNotice.getAuditSubmitState1()) {
				throw new BusinessException("已提交的审核意见不能再修改");
			}
			FinanceAuditLogEntity fale1 = new FinanceAuditLogEntity(DateUtil.now(), sb.toString(), loanNotice.getLeader2AuditState()?1L:0, "董事长:" + loanNotice.getLeader2Audit(), loanNotice.getLoanNoticeId(), 2L,FinanceSessionContext.getAccountId());
			financeAuditLogService.createFinanceAuditLogEntity(fale1);
			loanNotice.setAuditSubmitState1(Boolean.TRUE);
			loanNotice.setFinalState(ApiFinanceStateEnum.FINISHED.getCode());
			if (Boolean.FALSE == loanNotice.getAuditState1()) {
				initLoanNotice(loanNotice);
			} else {
//				LoanNoticeConsentParams params = new LoanNoticeConsentParams();
//				params.setLoanNoticeId(loanNotice.getLoanNoticeId());
//				params.setAuditRemark(loanNotice.getAuditRemark());
//				params.setBeneficiaryCreditCard(loanNotice.getBeneficiaryCreditCard());
//				params.setBeneficiaryBank(loanNotice.getBeneficiaryBank());
//				params.setBeneficiaryName(loanNotice.getBeneficiaryName());
//				params.setLoanNumber(loanNotice.getLoanNumber());
//				params.setLoanCreditCard(loanNotice.getLoanCreditCard());
//				params.setLoanDate(loanNotice.getLoanDate().toString());
//				params.setLoanMethod(loanNotice.getLoanMethod().ordinal());
//				consentLoanNotice(params);
//				if (Boolean.TRUE == loanNotice.getAutoNotice()) {
//					List<Long> inventoryIds = containerInventoryService.inquireLoanNoticeContainerInventoryIdList(loanNoticeId);
//					RecieveNoticeEntity rne = recieveNoticeService.inquireRecieveNoticeList(finance.getFinanceId()).get(0);
//					financeBulkstockNoticeActionApi.createTransportNotice(finance.getFinanceId(), finance.getFinanceNumber(), rne.getLogisticsCompanyId(), rne.getLogisticsCompanyName(), "运输通知", inventoryIds.toArray(new Long[inventoryIds.size()]));
//				}
//				List<FinanceBulkstockEntity> fbes = financeBulkstockService.inquireFinanceBulkstockList(loanNotice.getFinanceId());
//				FinanceCompleteResultEntity fcre = new FinanceCompleteResultEntity(loanNotice.getLoanNoticeId(), fbes.get(0).getBulkstockName(), fbes.get(0).getQuantity(), fbes.get(0).getUnit(), ApiTypeEnum.FK.getCode(), loanNotice.getLoanNoticeNumber(), DateUtil.now(), loanNotice.getEnterpriseName(), finance.getProductName(), loanNotice.getLoanAmount());
//				financeAuditLogService.createFinanceCompleteResultEntity(fcre);
			}	
			break;
		case 8:
			FinanceAuditLogEntity fale2 = new FinanceAuditLogEntity(DateUtil.now(), sb.toString(), loanNotice.getAuditState2()?1L:0, loanNotice.getAudit2(), loanNotice.getLoanNoticeId(), 2L,FinanceSessionContext.getAccountId());
			financeAuditLogService.createFinanceAuditLogEntity(fale2);
			loanNotice.setFinalState(ApiFinanceStateEnum.ZJ.getCode());
			loanNotice.setAuditSubmitState2(Boolean.TRUE);
			if (Boolean.FALSE == loanNotice.getAuditState2()) {
				loanNotice.setFinalState(ApiFinanceStateEnum.YY.getCode());
				loanNotice.setAuditSubmitState2(Boolean.FALSE);
				loanNotice.setAuditSubmitState1(Boolean.FALSE);
				SendLetterMessage.sendLetterMessage("loanNoticeAudit1_1", String.format(tmp, finance.getEnterpriseName(), finance.getFinanceNumber(), "运营审核"));
			} else {
				SendLetterMessage.sendLetterMessage("loanNoticeBusinessAudit_1", String.format(tmp, finance.getEnterpriseName(), finance.getFinanceNumber(), "风控审核"));
			}
			break;
		default:
			break;
		}
		loanNoticeService.renovateLoanNotice(loanNotice);
	}
	
	@Transactional
	private void initLoanNotice(LoanNoticeEntity loanNotice) {
		loanNotice.setFinalState(ApiFinanceStateEnum.ZJ.getCode());
		
		loanNotice.setLeader2AuditSubmitState(Boolean.FALSE);
		loanNotice.setLeader1AuditSubmitState(Boolean.FALSE);
		loanNotice.setFinancialLeaderAuditSubmitState(Boolean.FALSE);
		loanNotice.setFinancialAuditSubmitState(Boolean.FALSE);
		loanNotice.setAuditSubmitState1(Boolean.FALSE);
		
		loanNotice.setLeader2Audit("");
		loanNotice.setLeader1Audit("");
		loanNotice.setFinancialLeaderAudit("");
		loanNotice.setFinancialAudit("");
		loanNotice.setAudit1("");
		
		loanNotice.setLeader2AuditState(Boolean.TRUE);
		loanNotice.setLeader1AuditState(Boolean.TRUE);
		loanNotice.setFinancialLeaderAuditState(Boolean.TRUE);
		loanNotice.setFinancialAuditState(Boolean.TRUE);
		loanNotice.setAuditState1(Boolean.TRUE);
		
		loanNotice.setLeader2Auditor(null);
		loanNotice.setLeader1Auditor(null);
		loanNotice.setFinancialLeaderAuditor(null);
		loanNotice.setFinancialAuditor(null);
		loanNotice.setAuditor1(null);
		
		loanNotice.setLeader2AuditDate(null);
		loanNotice.setLeader1AuditDate(null);
		loanNotice.setFinancialLeaderAuditDate(null);
		loanNotice.setFinancialAuditDate(null);
		loanNotice.setAuditDate1(null);
		
		loanNotice.setCallback(Boolean.TRUE);
		loanNotice.setFinalState(ApiFinanceStateEnum.FINISHED.getCode());
		
		FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(loanNotice.getFinanceId());
		FinanceAuditEntity audit = financeAuditService.inquireLatestFinanceAudit(loanNotice.getFinanceId());
		finance.setFinanceState(FinanceStateEnum.APPROVE);
		finance.setConstractState(ConstractStateEnum.UNSUBMIT);
		initFinanceApplication(audit);
		audit.setFinanceAuditState(FinanceAuditEnum.PROCESSING);
		finance.setCallback(Boolean.TRUE);
		
		financeAuditService.updateFinanceAuditEntity(audit);
		financeApplicationService.updateFinanceApplication(finance);
		
		opposeLoanNotice(loanNotice.getLoanNoticeId());
	}
	
	private void initFinanceApplication(FinanceAuditEntity entity) {
		entity.setFinalState(ApiFinanceStateEnum.YW.getCode());

		entity.setBusinessAudit("");
		entity.setBusinessManageAudit("");
		entity.setRiskAudit("");
		entity.setRiskMemberAudit("");
		entity.setOperationManageAudit("");
		entity.setOperationAudit("");

		entity.setBusinessAuditDate(null);
		entity.setBusinessManageAuditDate(null);
		entity.setRiskAuditDate(null);
		entity.setRiskMemberAuditDate(null);
		entity.setOperationManageAuditDate(null);
		entity.setOperationAuditDate(null);

		entity.setBusinessAuditor("");
		entity.setBusinessManageAuditor("");
		entity.setRiskAuditor("");
		entity.setRiskMemberAuditor("");
		entity.setOperationManageAuditor("");
		entity.setOperationAuditor("");

		entity.setBusinessAuditorId(null);
		entity.setBusinessManageAuditorId(null);
		entity.setRiskAuditorId(null);
		entity.setRiskMemberAuditorId(null);
		entity.setOperationManageAuditorId(null);
		entity.setOperationAuditorId(null);

		entity.setBusinessAuditState(Boolean.TRUE);
		entity.setBusinessManageAuditState(Boolean.TRUE);
		entity.setRiskAuditState(Boolean.TRUE);
		entity.setRiskMemberAuditState(Boolean.TRUE);
		entity.setOperationManageAuditState(Boolean.TRUE);
		entity.setOperationAuditState(Boolean.TRUE);

		entity.setBusinessSubmitState(Boolean.FALSE);
		entity.setBusinessManageSubmitState(Boolean.FALSE);
		entity.setRiskSubmitState(Boolean.FALSE);
		entity.setRiskMemberSubmitState(Boolean.FALSE);
		entity.setOperationManageSubmitState(Boolean.FALSE);
		entity.setOperationSubmitState(Boolean.FALSE);

		entity.setCallback(Boolean.TRUE);
	}

	@Override
	public LoanNoticeDetail inquireLoanNoticeDetail(Long loanNoticeId) {
		LoanNoticeEntity entity = loanNoticeService.inquireLoanNoticeEntity(loanNoticeId);
		return FinanceLoanCastor.toLoanNoticeDetail(entity);
	}
	
	@Transactional
	@Override
	public PageList<LoanNoticeLineInfo> inquireLoanNoticePageList(String beginDate, String endDate, Long financeId, String financeNumber, Long enterpriseId, String enterpriseName, String bulkstockName, Integer productType, Integer loanState, PageCriteria page) {
		if (FinanceSessionContext.isEnterprise()) {
			enterpriseId = FinanceSessionContext.getEnterpriseId();
		}
		if (financeId != null && financeId != 0L) {
			FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(financeId);
			if (finance.getSettlementMethod() != null && finance.getSettlementMethod() == 2) {
				SupplierEntity se = supplierService.inquireSupplierDetail(finance.getReceive());
				enterpriseId = se.getSupplierId();
			}
			if (finance.getProductType() == ProductTypeEnum.PROXY_SALE) {
				enterpriseId = finance.getEnterpriseId();
			}
		}
		ApplicantLoanStateEnum las = null;
		List<Long> financeIds = financeApplicationService.getFinanceListIds(productType);
		if (loanState != null) {
			las = ApplicantLoanStateEnum.valueOf(loanState);
		} 
		PageList<LoanNoticeEntity> pageList = loanNoticeService.inquireLoanNoticeList(beginDate, endDate, financeId, financeNumber, enterpriseId, enterpriseName,bulkstockName, las,financeIds, page);
		PageList<LoanNoticeLineInfo> resultList = new PageList<LoanNoticeLineInfo>(page, pageList.getTotalRecordCount());
			for (LoanNoticeEntity entity : pageList) {
				resultList.add(FinanceLoanCastor.toLoanNoticeLineInfo(entity));
			}
		return resultList;
	}
	
	// ====================================================================================================================================================//
	@Transactional
	@Override
	public String createReceivables(Receivables params) {
		PickupApplicationEntity pickup = pickupApplicationService.inquirePickupApplication(params.getPickupId());
		pickup.setPickupApplicationCreateDateTime(null);
		pickup.setReceiveConfirmCreateDateTime(DateUtil.now());
		pickupApplicationService.renovatePickupApplication(pickup);

		if (ApplicationStateEnum.AGREE != pickup.getApplicationState() && ApplicationStateEnum.RECEIPT != pickup.getApplicationState() && ApplicationStateEnum.RELEASE != pickup.getApplicationState()) {
			throw new BusinessException("该提货状态不允许提交收款确认信息");
		}
		if (PickupMethodEnum.CASH_DELIVERY != pickup.getPickupMethod()) {
			throw new BusinessException("换货/换箱申请无需收款");
		}
		if (pickup.getPickupAmount().subtract(pickup.getReceivedAmount()).compareTo(params.getBeneficiaryAmount()) < 0) {
			throw new BusinessException("收款总额大于提货应还金额");
		}
		BigDecimal unConsentReceivablesAmount = receivablesService.inquirePickupUnConsentReceivablesAmount(pickup);
		if (pickup.getPickupAmount().subtract(pickup.getReceivedAmount()).subtract(unConsentReceivablesAmount).compareTo(params.getBeneficiaryAmount()) < 0) {
			throw new BusinessException("收款总额大于提货应还金额,待确认金额【" + unConsentReceivablesAmount + "】");
		}
		if (params.getCreditQuota() != null && params.getCreditQuota().compareTo(BigDecimal.ZERO) > 0) {
			FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(pickup.getFinanceId());
			if (finance.getCreditQuota().subtract(finance.getCreditQuotaConsume()).compareTo(params.getCreditQuota()) < 0) {
				throw new BusinessException("授信额度不够,不足以提货");
			}
		}

		ReceivablesEntity receivables = FinanceLoanCastor.fromReceivables(pickup, params);
		Long receivablesId = receivablesService.createReceivables(receivables);

		ReceivablesConsentParams consentParams = new ReceivablesConsentParams();
		consentParams.setReceivablesId(receivablesId);
		consentParams.setBeneficiaryMethod(1);
		consentParams.setBeneficiaryDate(DateUtil.formatDate(pickup.getDeliveryDate()));
		consentParams.setCreditQuota(params.getCreditQuota());
		consentParams.setAccountInfoId(params.getAccountInfoId());
		consentParams.setPaymentBank(params.getPaymentBank());
		consentParams.setPaymentCreditCard(params.getPaymentCreditCard());
		consentParams.setPaymentName(params.getPaymentName());
		consentParams.setPaymentName(params.getPaymentName());
		consentParams.setBeneficiaryBank(params.getBeneficiaryBank());
		consentParams.setBeneficiaryCreditCard(params.getBeneficiaryCreditCard());
		consentParams.setBeneficiaryName(params.getBeneficiaryName());
		consentParams.setFileUuids(params.getFileUuids());
		consentParams.setBeneficiaryNumber(params.getBeneficiaryNumber());
		consentParams.setIsAuto(params.getIsAuto());
		consentReceivables(consentParams);

		return receivablesId.toString();
	}

	@Transactional
	@Override
	public void updateReceivables(ReceivablesUpdateParams params) {
		ReceivablesEntity persist = receivablesService.inquireReceivables(params.getReceivablesId());
		if (ApplicantLoanStateEnum.WAIT_AUDIT != persist.getReceivablesState()) {
			throw new BusinessException("收款单已经审核确认,不允许修改!");
		}
		PickupApplicationEntity pickup = pickupApplicationService.inquirePickupApplication(params.getPickupId());

		BigDecimal unConsentReceivablesAmount = receivablesService.inquirePickupUnConsentReceivablesAmount(pickup);
		if (pickup.getPickupAmount().subtract(pickup.getReceivedAmount()).subtract(unConsentReceivablesAmount).compareTo(params.getBeneficiaryAmount()) < 0) {
			throw new BusinessException("收款总额大于提货应还金额,待确认金额【" + unConsentReceivablesAmount + "】");
		}

		ReceivablesEntity receivables = FinanceLoanCastor.fromReceivables(pickup, params);
		receivables.setReceivablesId(params.getReceivablesId());
		receivablesService.updateReceivables(receivables);
	}

	@Transactional
	@Override
	public void consentReceivables(ReceivablesConsentParams params) {
		ReceivablesEntity receivables = receivablesService.inquireReceivables(params.getReceivablesId());
		BeanUtils.copyProperties(params, receivables);
		receivables.setReceivablesState(ApplicantLoanStateEnum.AUDIT);
		receivables.setAuditDateTime(DateUtil.now());
		receivables.setAuditor(FinanceSessionContext.getAccountFullName());
		receivables.setAuditorId(FinanceSessionContext.getAccountId());
		receivablesService.renovateReceivables(receivables);
		// 更新提货申请收款金额
		PickupApplicationEntity pickup = pickupApplicationService.inquirePickupApplication(receivables.getPickupId());
		pickup.setReceivedAmount(pickup.getReceivedAmount().add(receivables.getBeneficiaryAmount()));
		if (pickup.getAuditAmount().compareTo(pickup.getReceivedAmount()) <= 0 && ApplicationStateEnum.AGREE == pickup.getApplicationState()) {
			pickup.setApplicationState(ApplicationStateEnum.RECEIPT);
			// 更新融资申请收款金额
			FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(receivables.getFinanceId());
			finance.setTotalReceivedAmount(finance.getTotalReceivedAmount().add(pickup.getFinanceValuation())); // 设置收款金额(货物本金)
			finance.setFinanceState(FinanceStateEnum.WAIT_PUTGOOD);
			if (receivables.getCreditQuota() != null && receivables.getCreditQuota().compareTo(BigDecimal.ZERO) != 0) {
				finance.setCreditQuotaConsume(finance.getCreditQuotaConsume().add(params.getCreditQuota()));
			}
			financeApplicationService.renovateFinanceApplication(finance);
			if (Boolean.TRUE == params.getIsAuto()) {
				List<Long> inventoryIds = pickupInventoryService.inquirePickupInventoryIdList(pickup.getPickupId());
				List<ContainerInventoryEntity> containerInventoryList = containerInventoryService.inquireContainerInventoryList(inventoryIds.toArray(new Long[inventoryIds.size()]));
				for (ContainerInventoryEntity cie : containerInventoryList) {
					cie.setSignState(Boolean.TRUE);
					cie.setSupervisionState(SupervisionStateEnum.ALREADY_SUPERVISE);
					containerInventoryService.updateContainerInventory(cie);
				}
			}
		}
		pickupApplicationService.renovatePickupApplication(pickup);

		// 项目动态
		FinanceProcessDetailEntity processDetailEntity = FinanceProcessCastor.fromFinancePickupReceivablesProcess(pickup, receivables);
		financeProcessDetailService.createFinanceProcessDetail(processDetailEntity);

		FinanceMoneyStatementEntity moneyEntity = FinanceLoanCastor.fromReceivables(receivables);
//		financeMoneyStatementService.createFinanceMoneyStatement(moneyEntity);

		// 直接核销
		FinanceWriteoffParams fps = new FinanceWriteoffParams();
		fps.setDisbursementBank(params.getPaymentBank());
		fps.setDisbursementCreditCard(params.getPaymentCreditCard());
		fps.setDisbursementName(params.getPaymentName());
		fps.setDrawee(params.getPaymentName());
		fps.setReceiptBank(params.getBeneficiaryBank());
		fps.setReceiptCreditCard(params.getBeneficiaryCreditCard());
		fps.setReceiptName(params.getBeneficiaryName());
		fps.setPayee(params.getBeneficiaryName());
		fps.setAccountInfoId(params.getAccountInfoId());
		fps.setWriteoffAmount(moneyEntity.getAmount());
		fps.setWriteoffDateTime(DateUtil.from(params.getBeneficiaryDate()));
		fps.setFileUuid(params.getFileUuids());
		fps.setMoneyStatementId(new Long[] { moneyEntity.getMoneyStatementId() });
		fps.setVerifiAmount(new BigDecimal[] { moneyEntity.getAmount() });
		fps.setWriteoffNumber(params.getBeneficiaryNumber());
//		verifiReceiptMoneyStatement(fps);

		// 生成企业付款单
		BillReceivableEntity bre = FinanceLoanCastor.toBillReceivableEntity(BillTypeEnum.RECEIVE, fps);
		billReceivableService.createBillReceivable(bre);

//		FinanceMoneyStatementEntity fmse = financeMoneyStatementService.inquireFinanceMoneyStatementDetail(moneyEntity.getMoneyStatementId());
//		fmse.setBillReceivableId(bre.getBillReceivableId());
//		financeMoneyStatementService.renovateFinanceMoneyStatement(fmse);
	}

	@Transactional
	@Override
	public void disableReceivables(Long receivablesId) {
		ReceivablesEntity receivablesEntity = receivablesService.inquireReceivables(receivablesId);
		receivablesService.disableReceivables(receivablesEntity);
		PickupApplicationEntity pickupEntity = pickupApplicationService.inquirePickupApplication(receivablesEntity.getPickupId());
		// 更新提货申请收款金额
		pickupEntity.setReceivedAmount(pickupEntity.getReceivedAmount().subtract(receivablesEntity.getBeneficiaryAmount()));
		pickupApplicationService.updatePickupApplication(pickupEntity);
		// 更新融资申请收款金额
		FinanceApplicationEntity financeEntity = financeApplicationService.inquireFinanceApplicationEntity(receivablesEntity.getFinanceId());
		financeEntity.setTotalReceivedAmount(financeEntity.getTotalReceivedAmount().subtract(receivablesEntity.getBeneficiaryAmount()));
		financeApplicationService.renovateFinanceApplication(financeEntity);
		receivablesService.updateReceivables(receivablesEntity);
	}

	@Override
	public ReceivablesDetail inquireReceivablesDetail(Long receivablesId) {
		ReceivablesEntity entity = receivablesService.inquireReceivablesDetail(receivablesId);
		return FinanceLoanCastor.toReceivablesDetail(entity);
	}

	@Override
	public PageList<ReceivablesLineInfo> inquireReceivablesPageList(String beginDate, String endDate, Long pickupId, Long financeId, String financeNumber, Long enterpriseId, String enterpriseName, PageCriteria page) {
		if (FinanceSessionContext.isEnterprise()) {
			enterpriseId = FinanceSessionContext.getEnterpriseId();
		}
		PageList<ReceivablesEntity> pageList = receivablesService.inquireReceivablesPageList(beginDate, endDate, pickupId, financeId, financeNumber, enterpriseId, enterpriseName, page);
		PageList<ReceivablesLineInfo> resultList = new PageList<>(page, pageList.getTotalRecordCount());
		for (ReceivablesEntity entity : pageList) {
			resultList.add(FinanceLoanCastor.toReceivablesLineInfo(entity));
		}
		return resultList;
	}

	// ====================================================================================================================================================//
	@Transactional
	@Override
	public String createFinanceCredit(Long financeId, BigDecimal creditAmount, BigDecimal valuation, String remark, Integer reson, Long[] bulkstockIds, BigDecimal[] evaluateAmounts) {
		if (bulkstockIds.length <= 0) {
			throw new BusinessException("估值货物不允许为空");
		}
		FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(financeId);
		FinanceCreditEntity entity = FinanceLoanCastor.fromFinanceCredit(finance, creditAmount, valuation, remark, reson);
		Long creditId = financeCreditService.createFinanceCredit(entity);
		finance.setValuation(valuation);
		finance.setCreditQuota(finance.getCreditQuota().add(creditAmount));
		financeApplicationService.renovateFinanceApplication(finance);

		for (int i = 0; i < bulkstockIds.length; i++) {
			BigDecimal evaluateAmount = CollectionUtils.getArrayIndexValue(evaluateAmounts, i);
			FinanceBulkstockEntity fbe = financeBulkstockService.inquireFinanceBulkstock(bulkstockIds[i]);
			FinanceCreditBulkstockEntity bulkstock = FinanceLoanCastor.fromFinanceCredit(fbe, creditId, bulkstockIds[i], evaluateAmount);
			financeCreditBulkstockService.createFinanceCreditBulkstock(bulkstock);
			fbe.setEvaluatePrice(bulkstock.getEvaluateAmount());
			financeBulkstockService.renovateFinanceBulkstock(fbe);
		}
		return creditId.toString();
	}

	@Override
	@Transactional
	public String additionalFinanceDeposit(Long financeId, BigDecimal amount, String remark, Integer reson) {
		FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(financeId);
		FinanceCreditEntity entity = FinanceLoanCastor.fromFinanceCreditDeposit(finance, amount, remark, reson);
		Long creditId = financeCreditService.createFinanceCredit(entity);
		return creditId.toString();
	}

	@Override
	@Transactional
	public void auditAdditionalFinanceDeposit(Long creditId, BigDecimal riskBail, String auditRemark, Integer auditState) {
		FinanceCreditEntity entity = financeCreditService.inquireFinanceCredit(creditId);
		if (auditState == 2) {
			if (riskBail == null) {
				riskBail = BigDecimal.ZERO;
			}
			FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(entity.getFinanceId());
			entity.setAuditDateTime(DateUtils.now());
			entity.setAuditor(FinanceSessionContext.getAccountFullName());
			entity.setAuditorId(FinanceSessionContext.getAccountId());
			entity.setAuditState(AuditStateEnum.PASS);
			entity.setAuditRemark(auditRemark);
			entity.setRiskBail(riskBail);
			entity.setSubmitBail(entity.getRiskBail().add(entity.getCreditAmount()));
			financeCreditService.updateFinanceCredit(entity);
			finance.setBail(finance.getBail().add(entity.getSubmitBail()));
			financeApplicationService.renovateFinanceApplication(finance);
			FinanceMoneyStatementEntity moneyEntity = FinanceLoanCastor.fromFinanceAdditionBail(finance, entity);
			financeMoneyStatementService.createFinanceMoneyStatement(moneyEntity);

			// 发送消息
			FinanceLetterBlockingQueue.putEnterpriseExceptionLetter(getFinanceEnterpriseId(finance.getFinanceId()), "保证金追加", "exception.detained");
		} else if (auditState == 3) {
			entity.setAuditDateTime(DateUtils.now());
			entity.setAuditor(FinanceSessionContext.getAccountFullName());
			entity.setAuditorId(FinanceSessionContext.getAccountId());
			entity.setAuditState(AuditStateEnum.REFUSE);
			entity.setAuditRemark(auditRemark);
			financeCreditService.updateFinanceCredit(entity);
		}

	}

	@Override
	@Transactional
	public String createFinanceReplenishCredit(Long financeId, BigDecimal replenishAmount, BigDecimal valuation, String remark, Integer reson, Long[] bulkstockIds, BigDecimal[] evaluateAmounts, Long loanNoticeId) {
		if (bulkstockIds.length <= 0) {
			throw new BusinessException("估值货物不允许为空");
		}

		// TODO 查询该放款批次下是否存在补货
		List<FinanceCreditEntity> lt = financeCreditService.inquireFinanceCreditPageLists(AdjustmentEnum.REPLENISH, financeId, AuditStateEnum.PASS, null, null, loanNoticeId, PageCriteria.defaultInstance());
		if (lt != null && lt.size() > 0) {
			throw new BusinessException("该放款单下存在换货！");
		}

		List<ContainerInventoryEntity> inventories = containerInventoryService.inquireLoanNoticeContainerInventoryList(loanNoticeId);
		List<FinanceCreditReplenishContainerEntity> sourceContainers = new ArrayList<>();
		for (ContainerInventoryEntity cie : inventories) {
			if (!cie.getAbnormal()) {
				throw new BusinessException("该放款单下存在异常箱未处理");
			}
			if (cie.getPickupId() != null) {
				PickupApplicationEntity pickup = pickupApplicationService.inquirePickupApplication(cie.getPickupId());
				if (ApplicationStateEnum.NOT_APPROVE == pickup.getApplicationState()) {
					throw new BusinessException("该放款单下存在提货待审批的箱信息");
				}
				continue;
			}
			FinanceCreditReplenishContainerEntity entity = new FinanceCreditReplenishContainerEntity();
			entity.setInventoryId(cie.getInventoryId());
			sourceContainers.add(entity);
		}
		FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(financeId);
		FinanceCreditEntity credit = FinanceLoanCastor.fromFinanceCreditReplenish(finance, replenishAmount, valuation, remark, reson, loanNoticeId);
		Long creditId = financeCreditService.createFinanceCredit(credit);

		for (int i = 0; i < bulkstockIds.length; i++) {
			BigDecimal evaluateAmount = CollectionUtils.getArrayIndexValue(evaluateAmounts, i);
			FinanceBulkstockEntity fbe = financeBulkstockService.inquireFinanceBulkstock(bulkstockIds[i]);
			FinanceCreditBulkstockEntity bulkstock = FinanceLoanCastor.fromFinanceCredit(fbe, creditId, bulkstockIds[i], evaluateAmount);
			financeCreditBulkstockService.createFinanceCreditBulkstock(bulkstock);
		}

		for (FinanceCreditReplenishContainerEntity fcrce : sourceContainers) {
			fcrce.setCreditId(creditId);
			fcrce.setReplenishState(credit.getReplenishState());
			financeCreditReplenishContainerService.createFinanceCreditReplenishContainer(fcrce);
		}
		return creditId.toString();
	}

	@Override
	@Transactional
	public void consentFinanceReplenishCredit(Long creditId, String auditRemark) {
		FinanceCreditEntity credit = financeCreditService.inquireFinanceCredit(creditId);
		credit.setAuditDateTime(DateUtils.now());
		credit.setAuditor(FinanceSessionContext.getAccountFullName());
		credit.setAuditorId(FinanceSessionContext.getAccountId());
		credit.setAuditState(AuditStateEnum.PASS);
		credit.setAuditRemark(auditRemark);
		financeCreditService.updateFinanceCredit(credit);
	}

	@Override
	public void opposeFinanceReplenishCredit(Long creditId, String auditRemark) {
		FinanceCreditEntity entity = financeCreditService.inquireFinanceCredit(creditId);
		entity.setAuditDateTime(DateUtils.now());
		entity.setAuditor(FinanceSessionContext.getAccountFullName());
		entity.setAuditorId(FinanceSessionContext.getAccountId());
		entity.setAuditState(AuditStateEnum.REFUSE);
		entity.setAuditRemark(auditRemark);
		financeCreditService.updateFinanceCredit(entity);
		if (AdjustmentEnum.REPLENISH == entity.getAdjustment()) {
			List<FinanceCreditReplenishContainerEntity> containers = financeCreditReplenishContainerService.inquireCreditReplenishContainerList(creditId);
			for (FinanceCreditReplenishContainerEntity container : containers) {
				financeCreditReplenishContainerService.removeFinanceCreditReplenishContainer(container);
			}
		}
	}

	@Override
	@Transactional
	public void submitFinanceReplenishBulkstock(Long creditId, Long[] bulkstockInfoIds, String[] manufacturers, String[] originPlaces, BigDecimal[] weights, BigDecimal[] bulkstockPrices) {
		FinanceCreditEntity credit = financeCreditService.inquireFinanceCredit(creditId);
		for (int i = 0; i < bulkstockInfoIds.length; i++) {
			BulkstockInfoEntity bulkstockInfo = bulkstockInfoService.inquireBulkstockInfo(bulkstockInfoIds[i]);
			BigDecimal bulkstockPrice = CollectionUtils.getArrayIndexValue(bulkstockPrices, i);
			String manufacturer = CollectionUtils.getArrayIndexValue(manufacturers, i);
			String originPlace = CollectionUtils.getArrayIndexValue(originPlaces, i);
			BigDecimal weight = CollectionUtils.getArrayIndexValue(weights, i);
			FinanceCreditReplenishEntity replenish = FinanceLoanCastor.fromFinanceCreditReplenishBulkstock(credit, bulkstockInfo, bulkstockPrice, manufacturer, originPlace, weight);
			financeCreditReplenishService.createFinanceCreditReplenish(replenish);
		}
		credit.setReplenishMethod(ReplenishMethodEnum.BULKSTOCK);
		credit.setReplenish(ReplenishEnum.FINISHED);
		financeCreditService.renovateFinanceCredit(credit);
	}

	@Override
	public void submitFinanceReplenishContainer(Long creditId, String[] waybillNumbers, String[] caseNumbers, String[] caseSizes, String[] facingSlips, String[] trayNumbers, Long[] bulkstockInfoIds, BigDecimal[] weights,
			String[] manufacturers, String[] originPlaces) {
		FinanceCreditEntity credit = financeCreditService.inquireFinanceCredit(creditId);
		Map<Long, FinanceCreditReplenishEntity> replenishs = new HashMap<>();
		for (int i = 0; i < waybillNumbers.length; i++) {
			FinanceCreditContainerEntity container = new FinanceCreditContainerEntity();
			container.setWaybillNumber(CollectionUtils.getArrayIndexValue(waybillNumbers, i));
			container.setCaseNumber(CollectionUtils.getArrayIndexValue(caseNumbers, i));
			container.setCaseSize(CollectionUtils.getArrayIndexValue(caseSizes, i));
			container.setCreditId(credit.getCreditId());
			container.setFacingSlip(CollectionUtils.getArrayIndexValue(facingSlips, i));
			financeCreditContainerService.createFinanceCreditContainer(container);

			BulkstockInfoEntity bulkstockInfo = bulkstockInfoService.inquireBulkstockInfo(bulkstockInfoIds[i]);
			String trayNumber = CollectionUtils.getArrayIndexValue(trayNumbers, i);
			String manufacturer = CollectionUtils.getArrayIndexValue(manufacturers, i);
			String originPlace = CollectionUtils.getArrayIndexValue(originPlaces, i);
			BigDecimal weight = CollectionUtils.getArrayIndexValue(weights, i);
			FinanceCreditContainerBulkstockEntity bulkstock = FinanceLoanCastor.fromFinanceReplenishContainer(container, bulkstockInfo, trayNumber, weight, originPlace, manufacturer);
			financeCreditContainerBulkstockService.createFinanceCreditContainerBulkstock(bulkstock);
			FinanceCreditReplenishEntity replenish = replenishs.get(bulkstock.getBulkstockInfoId());
			if (replenish == null) {
				replenish = FinanceLoanCastor.fromFinanceReplenishContainer(bulkstockInfo, container, bulkstock);
				replenishs.put(replenish.getBulkstockInfoId(), replenish);
			}
			replenish.setWeight(replenish.getWeight().add(bulkstock.getWeight()));
			replenish.setQuantity(replenish.getQuantity().add(bulkstock.getQuantity()));
			replenish.setValuationQuantity(replenish.getWeight());
		}
		for (Entry<Long, FinanceCreditReplenishEntity> entry : replenishs.entrySet()) {
			financeCreditReplenishService.createFinanceCreditReplenish(entry.getValue());
		}
		credit.setReplenishMethod(ReplenishMethodEnum.CONTAINER);
		credit.setReplenish(ReplenishEnum.FINISHED);
		financeCreditService.renovateFinanceCredit(credit);
	}

	@Override
	@Transactional
	public void confirmFinanceReplenishCredit(Long creditId, Long[] replenishId, BigDecimal[] evaluatePrice, BigDecimal[] lowestPrice, BigDecimal[] highestPrice) {
		FinanceCreditEntity credit = financeCreditService.inquireFinanceCredit(creditId);
		if (ReplenishStateEnum.WAIT != credit.getReplenishState()) {
			throw new BusinessException("已确认过的补货不能再次确认！");
		}

		List<FinanceCreditReplenishEntity> replenishs = financeCreditReplenishService.inquireFinanceCreditReplenishList(creditId);
		BigDecimal evaluateAmount = BigDecimal.ZERO; // 合计新增货物的评估总额
		for (FinanceCreditReplenishEntity replenish : replenishs) {
			for (int i = 0; i < replenishId.length; i++) {
				if (!replenish.getReplenishId().equals(replenishId[i])) {
					continue;
				}
				replenish.setEvaluatePrice(CollectionUtils.getArrayIndexValue(evaluatePrice, i));
				replenish.setHighestPrice(CollectionUtils.getArrayIndexValue(highestPrice, i));
				replenish.setLowestPrice(CollectionUtils.getArrayIndexValue(lowestPrice, i));
				evaluateAmount = evaluateAmount.add(replenish.getEvaluatePrice().multiply(replenish.getValuationQuantity()));
			}
		}
		for (FinanceCreditReplenishEntity replenish : replenishs) {
			if (replenish.getEvaluatePrice() == null) {
				throw new BusinessException("补货估值评审不允许为空");
			}
		}
		List<FinanceCreditBulkstockEntity> list = financeCreditBulkstockService.inquireFinanceCreditBulkstockList(creditId);
		Map<Long, FinanceCreditBulkstockEntity> creditBulkstocks = new HashMap<>();
		for (FinanceCreditBulkstockEntity fcb : list) {
			creditBulkstocks.put(fcb.getBulkstockId(), fcb);
		}
		// 箱货估值调整 1.合计新增货物的评估总额+合计涉及补货的箱评估总额
		BigDecimal financeAmount = BigDecimal.ZERO;
		List<FinanceCreditReplenishContainerEntity> containers = financeCreditReplenishContainerService.inquireCreditReplenishContainerList(creditId);
		List<ContainerBulkstockEntity> sourceBulkstocks = new ArrayList<>();
		for (FinanceCreditReplenishContainerEntity container : containers) {
			List<ContainerBulkstockEntity> cbes = containerBulkstockService.inquireContainerBulkstockList(container.getInventoryId());
			for (ContainerBulkstockEntity cbe : cbes) {
				FinanceCreditBulkstockEntity fcbe = creditBulkstocks.get(cbe.getBulkstockId());
				cbe.setEvaluatePrice(fcbe.getEvaluateAmount());
				evaluateAmount = evaluateAmount.add(cbe.getEvaluatePrice().multiply(cbe.getValuationQuantity()));
				financeAmount = financeAmount.add(cbe.getValuationFinanceAmount());
				sourceBulkstocks.add(cbe);
			}
		}
		// 变更换货箱中货物的融资单价 原货物的融资总额
		BigDecimal sourceFinanceAmount = BigDecimal.ZERO;
		for (ContainerBulkstockEntity cbe : sourceBulkstocks) {
			cbe.setFinancePrice(cbe.getEvaluatePrice().multiply(financeAmount).divide(evaluateAmount, 2, BigDecimal.ROUND_HALF_UP));
			containerBulkstockService.renovateContainerBulkstock(cbe);
			sourceFinanceAmount = sourceFinanceAmount.add(cbe.getValuationFinanceAmount());
		}
		// 计算补进货物的融资单价
		for (FinanceCreditReplenishEntity replenish : replenishs) {
			replenish.setFinancePrice(replenish.getEvaluatePrice().multiply(financeAmount).divide(evaluateAmount, 10, BigDecimal.ROUND_HALF_UP));
		}
		credit.setReplenishFinanceAmount(financeAmount.subtract(sourceFinanceAmount));
		Map<Long, FinanceBulkstockEntity> financeBulkstocks = processFinanceReplenishBulkstockCredit(credit, replenishs); // 合并至融资货物中
		for (FinanceCreditReplenishEntity replenish : replenishs) {
			financeCreditReplenishService.renovateFinanceCreditReplenish(replenish);
		}
		if (ReplenishMethodEnum.BULKSTOCK == credit.getReplenishMethod()) {
			credit.setReplenishState(ReplenishStateEnum.CONFIRM);
			financeCreditService.renovateFinanceCredit(credit);
		} else if (ReplenishMethodEnum.CONTAINER == credit.getReplenishMethod()) { // 补箱确认
			// 全部补货确认监管
			credit.setReplenishState(ReplenishStateEnum.FINISHED);
			financeCreditService.renovateFinanceCredit(credit);
			for (FinanceCreditReplenishContainerEntity e : containers) {
				e.setReplenishState(credit.getReplenishState());
				financeCreditReplenishContainerService.renovateFinanceCreditReplenishContainer(e);
			}
			processFinanceReplenishContainerCredit(financeBulkstocks, credit); // 合并至融资项目的箱信息中

		}
	}

	@Override
	public FinanceCreditDetail inquireFinanceCreditDetail(Long creditId) {
		FinanceCreditEntity financeCredit = financeCreditService.inquireFinanceCredit(creditId);
		return FinanceLoanCastor.toFinanceCreditDetail(financeCredit);
	}

	@Override
	public FinanceCreditDetail inquireFinanceReplenishDetail(Long creditId) {
		FinanceCreditEntity financeCredit = financeCreditService.inquireFinanceCredit(creditId);
		return FinanceLoanCastor.toFinanceCreditDetail1(financeCredit);
	}

	@Override
	public PageList<FinanceCreditLineInfo> inquireFinanceCreditPageList(Integer adjustment, Long financeId, Integer auditState, Long creditId, PageCriteria page) {
		Long enterpriseId = null;
		if (FinanceSessionContext.getAppKey() == FinanceConstant.APPKEY_ENTERPRISE_ANDROID || FinanceSessionContext.getAppKey() == FinanceConstant.APPKEY_ENTERPRISE_IOS
				|| FinanceSessionContext.getAppKey() == FinanceConstant.APPKEY_ENTERPRISE_WEB) {
			enterpriseId = FinanceSessionContext.getEnterpriseId();
		}
		PageList<FinanceCreditEntity> pages = financeCreditService.inquireFinanceCreditPageList(AdjustmentEnum.valueOf(adjustment), financeId, AuditStateEnum.valueOf(auditState), creditId, enterpriseId, null, page);
		PageList<FinanceCreditLineInfo> results = new PageList<>(page, pages.getTotalRecordCount());
		for (FinanceCreditEntity entity : pages) {
			results.add(FinanceLoanCastor.toFinanceCreditLineInfo(entity));
		}
		return results;
	}

	// ====================================================================================================================================================//
	@Override
	public PageList<FinanceMoneyStatement> inquireReceiptMoneyStatementPageList(Long financeId, String[] statementSource, String financeNumber, String disbursementName, String statementBeginDate, String statementEndDate,
			BigDecimal minSourceAmount, BigDecimal maxSourceAmount, String statementNumber, Boolean verifiCancelState, Integer productType, PageCriteria page) {
		Integer beginStatementDate = DateUtil.parseDateInt(statementBeginDate);
		Integer endStatementDate = DateUtil.parseDateInt(statementEndDate);
		Long receiptTenantId = FinanceSessionContext.getAccountTenantId();
		if (statementSource != null && statementSource.length == 1 && StringUtils.isBlank(statementSource[0])) {
			statementSource = null;
		}
		PageList<FinanceMoneyStatementEntity> pages = financeMoneyStatementService.inquireFinanceMoneyStatementPageList(financeId, statementSource, receiptTenantId, null, null, disbursementName, financeNumber, beginStatementDate,
				endStatementDate, minSourceAmount, maxSourceAmount, null, statementNumber, verifiCancelState, null, productType, page);
		PageList<FinanceMoneyStatement> results = new PageList<>(page, pages.getTotalRecordCount());
		for (FinanceMoneyStatementEntity entity : pages) {
			results.add(FinanceLoanCastor.toFinanceMoneyStatement(entity));
		}
		return results;
	}

	@Override
	public PageList<FinanceMoneyStatement> inquireDisbursementMoneyStatementPageList(Long financeId, String[] statementSource, String financeNumber, String receiptName, String statementBeginDate, String statementEndDate, BigDecimal minSourceAmount, BigDecimal maxSourceAmount,
			String statementNumber, Boolean verifiCancelState, Integer productType, PageCriteria page) {
		Integer beginStatementDate = DateUtil.parseDateInt(statementBeginDate);
		Integer endStatementDate = DateUtil.parseDateInt(statementEndDate);
		Long disbursementTenantId = FinanceSessionContext.getAccountTenantId();
		PageList<FinanceMoneyStatementEntity> pages = financeMoneyStatementService.inquireFinanceMoneyStatementPageList(financeId, statementSource, null, receiptName, disbursementTenantId, null, financeNumber, beginStatementDate, endStatementDate,
				minSourceAmount, maxSourceAmount, null, statementNumber, null, verifiCancelState, productType, page);
		PageList<FinanceMoneyStatement> results = new PageList<>(page, pages.getTotalRecordCount());
		for (FinanceMoneyStatementEntity entity : pages) {
			results.add(FinanceLoanCastor.toFinanceMoneyStatement(entity));
		}
		return results;
	}
	
	@Override
	@Transactional
	public void verifimonthReceiptMoneyStatement(FinanceWriteoffParams params) {
		ReceiptRecordEntity rre = new ReceiptRecordEntity();
		BeanUtils.copyProperties(params, rre);
		rre.setOperator(FinanceSessionContext.getAccountFullName());
		rre.setOperatorId(FinanceSessionContext.getAccountId());
		rre.setCareteMethod(params.getCreateMethod());
		receiptRecordService.createReceiptRecord(rre);
		
		for (int i = 0; i < params.getMoneyStatementId().length; i++) {
			FinanceRecordCorrespondingInfoEntity entity = new FinanceRecordCorrespondingInfoEntity();
			entity.setAmount(params.getVerifiAmount()[i]);
			entity.setMoneyStatementId(params.getMoneyStatementId()[i]);
			entity.setReceipRecordtId(rre.getReceipRecordtId());
			financeRecordCorrespondingInfoService.createFinanceRecordCorrespondingInfo(entity);
			
			FinanceWriteoffParams p = new FinanceWriteoffParams();
			BeanUtils.copyProperties(params, p, "moneyStatementId", "verifiAmount");
			p.setMoneyStatementId(new Long[]{params.getMoneyStatementId()[i]});
			p.setVerifiAmount(new BigDecimal[]{params.getVerifiAmount()[i]});
			verifiReceiptMoneyStatement(p);
		}
	}

	@Override
	@Transactional
	public String verifiReceiptMoneyStatement(FinanceWriteoffParams params) {
		BillReceivableEntity be;
		if (params.getBillReceivableId() != null) {
			be = billReceivableService.inquireBillReceivable(params.getBillReceivableId());
			if (params.getWriteoffAmount().compareTo(be.getBalance()) >= 0) {
				throw new BusinessException("余额不足！");
			}
		}
		
		List<FinanceMoneyStatementEntity> statements = new ArrayList<>();
		Map<Long, BigDecimal> receiptAmounts = new HashMap<>();
		if (params.getMoneyStatementId() != null && params.getMoneyStatementId().length > 0) {
			statements = financeMoneyStatementService.inquireFinanceMoneyStatementList(FinanceSessionContext.getAccountTenantId(), null, params.getMoneyStatementId());
			if (statements.size() != params.getMoneyStatementId().length) {
				throw new BusinessException("该帐户下的收款流水与提交的核销流水不一致");
			}
			for (int i = 0; i < params.getMoneyStatementId().length; i++) {
				Long moneyStatementId = params.getMoneyStatementId()[i];
				receiptAmounts.put(moneyStatementId, params.getVerifiAmount()[i]);
			}
		}
		FinanceWriteoffEntity writeoff = FinanceLoanCastor.fromFinanceReceiptWriteoffParams(params);

		Long writeoffId = financeWriteoffService.createFinanceWriteoff(writeoff);
		List<FinanceWriteoffStatementEntity> writeoffStatements = FinanceLoanCastor.fromFinanceWriteoffParams(writeoff, params);
		for (FinanceWriteoffStatementEntity writeoffStatement : writeoffStatements) {
			financeWriteoffStatementService.createFinanceWriteoffStatement(writeoffStatement);
		}

		// 流水核销
		for (FinanceMoneyStatementEntity statement : statements) {
			statement.setReceiptAmount(statement.getReceiptAmount().add(receiptAmounts.get(statement.getMoneyStatementId())));
			statement.setReceiptBalance(statement.getAmount().subtract(statement.getReceiptAmount()).subtract(statement.getCreditQuota()));

			// 生成企业收付款记录
			BillReceivableEntity bre;
			if (params.getBillReceivableId() == null) {
				bre = FinanceLoanCastor.toBillReceivableEntity(BillTypeEnum.RECEIVE, params);
				bre.setMoneyStatementId(statement.getMoneyStatementId());
				billReceivableService.createBillReceivable(bre);
			} else {
				bre = billReceivableService.inquireBillReceivable(params.getBillReceivableId());
			}
			if (bre.getAmount().compareTo(params.getWriteoffAmount()) >= 0) {
				bre.setBalance(bre.getAmount().subtract(params.getWriteoffAmount()));
			} else {
				throw new BusinessException("余额不足");
			}
			billReceivableService.updateBillReceivable(bre);
			
			if (statement.getReceiptBalance().compareTo(BigDecimal.ZERO) < 0 && (("RECEIVABLES".equals(statement.getStatementSource())) || ("RECEIVABLES_WAREHOUSE".equals(statement.getStatementSource())))) {
				throw new BusinessException("核销金额不能超过应收金额!");
			}
			if (statement.getReceiptBalance().compareTo(BigDecimal.ZERO) == 0) {
				statement.setReceiptVerifiState(Boolean.TRUE);
				statement.setReceiptVerifiDateTime(DateUtil.now());
				statement.setReceiptVerifiAccount(FinanceSessionContext.getAccountFullName());
				statement.setReceiptVerifiAccountId(FinanceSessionContext.getAccountId());
			}
			
			if (statement.getStatementSource().equals("INSURANCE")) {
				InsuranceEntity entity = insuranceService.inquireInsuranceEntity(statement.getStatementSourceId());
				entity.setAlreadyPremium(entity.getAlreadyPremium().add(statement.getAmount()));
				insuranceService.updateFinanceInsurance(entity);
			} else if (statement.getStatementSource().equals("LOANS_MONEY")) {
				CapitalAccountInfoEntity bank = bankInfoService.inquireBankInfoDetail(params.getAccountInfoId());
				bank.setAccountAmount(bank.getAccountAmount().add(statement.getAmount()));
				bankInfoService.updateBankInfo(bank);
			} else if (statement.getStatementSource().equals("RECEIVABLES")) {
				if (statement.getFinanceId() != null) {
					FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(statement.getFinanceId());
					finance.setTotalReceivedAmount(finance.getTotalReceivedAmount().add(params.getWriteoffAmount()));
					
					if (ProductTypeEnum.MANIFEST_PLEDGE == finance.getProductType() || ProductTypeEnum.PURCHASING_STORAGE == finance.getProductType() || ProductTypeEnum.PROXY_SALE == finance.getProductType()) {
						PickupApplicationEntity pae = pickupApplicationService.inquirePickupApplication(statement.getStatementSourceId());
						List<ContainerInventoryEntity> inventories = containerInventoryService.inquirePickupContainerInventoryList(pae.getPickupId());
						StringBuffer recepitIds = new StringBuffer();
						for (ContainerInventoryEntity cie : inventories) {
							recepitIds.append(cie.getReceiptId()).append(",");
							cie.setSignState(Boolean.TRUE);
							cie.setAbnormal(Boolean.TRUE);
							cie.setSupervisionState(SupervisionStateEnum.ALREADY_SUPERVISE);
							containerInventoryService.renovateContainerInventory(cie);
						}
						
						if (recepitIds.length() > 0) {
							recepitIds.deleteCharAt(recepitIds.length() - 1);
						}
						
						finance.setFinanceState(FinanceStateEnum.SIGN);
					}
					
					financeApplicationService.updateFinanceApplication(finance);
					financeApplicationActionApi.initEnterpriseEnterprise(finance.getEnterpriseId());
				}
//				EnterpriseGradeEntity grade = enterpriseGradeService.inquireEnterpriseGrade(statement.getDisbursementId());
//				grade.setCreditAlready(grade.getCreditAlready().subtract(statement.getReceiptAmount()));
//				enterpriseGradeService.persistEnterpriseGrade(grade);
			} else if (statement.getStatementSource().equals("RECEIVABLES_WAREHOUSE")) {
				FinanceApplicationEntity finance1 = financeApplicationService.inquireFinanceApplicationEntity(statement.getFinanceId());
				finance1.setTotalReceivedAmount(finance1.getTotalReceivedAmount().add(params.getWriteoffAmount()));
				PickupApplicationWarehouseDetail pawd = financePickupApplicationWarehouseApi.inquireFinancePickupApplicationWarehouse(statement.getStatementSourceId());
				for (PickupBulkstockWarehouseDetail pbwd : pawd.getBulkstockList()) {
					StringBuffer sql = new StringBuffer();
					sql.append("SELECT (T1.WEIGHT - IFNULL(T2.PICKUP_QUANTITY, 0)) as WEIGHT, T1.LOCATION_ID as LOCATION_ID, BULKSTOCK_NAME, SPECIFICATION, PRODUCT_TYPE, BULKSTOCK_INFO_ID, WAREHOUSE_NAME, T1.FINANCE_ID AS FINANCE_ID, T1.FINANCE_NUMBER AS FINANCE_NUMBER, T1.APPLICATION_DT AS APPLICATION_DT, T1.LOCATION_AREA AS LOCATION_AREA, T1.LOCATION_NAME AS LOCATION_NAME FROM (SELECT SUM(WEIGHT) AS WEIGHT, LOCATION_ID, BULKSTOCK_NAME, SPECIFICATION, c.PRODUCT_TYPE, BULKSTOCK_INFO_ID, WAREHOUSE_NAME, a.FINANCE_ID AS FINANCE_ID, a.FINANCE_NUMBER AS FINANCE_NUMBER, c.APPLICATION_DT AS APPLICATION_DT, a.LOCATION_AREA AS LOCATION_AREA, a.LOCATION_NAME AS LOCATION_NAME FROM fin_container_inventory a, fin_container_bulkstock b, fin_finance_application c WHERE a.INVENTORY_ID = b.INVENTORY_ID");
					sql.append(" AND a.FINANCE_NUMBER ='").append(pbwd.getFinanceNumber() + "'");
					sql.append(" AND a.FINANCE_ID = c.FINANCE_ID AND c.FINANCE_STATE IN (9,25,26,27,28,29) GROUP BY a.FINANCE_ID) T1 LEFT JOIN (SELECT SUM(PICKUP_QUANTITY) AS PICKUP_QUANTITY, LOCATION_ID, FINANCE_NUMBER FROM fin_pickup_bulkstock_warehouse d, FIN_PICKUP_APPLICATION_WAREHOUSE e where d.PICKUP_ID = e.PICKUP_ID AND e.PICKUP_STATE IN(11, 12) GROUP BY FINANCE_NUMBER, LOCATION_ID) T2 ON T1.LOCATION_ID = T2.LOCATION_ID AND T1.FINANCE_NUMBER = T2.FINANCE_NUMBER WHERE T1.LOCATION_ID IS NOT NULL AND T1.LOCATION_ID <> '';");
					Session session = SessionRepository.getCurrentSession();

					List<Object> datas = session.createSQLQuery(sql.toString()).addScalar("WEIGHT").addScalar("LOCATION_ID").addScalar("BULKSTOCK_NAME").addScalar("PRODUCT_TYPE").addScalar("BULKSTOCK_INFO_ID").addScalar("WAREHOUSE_NAME").addScalar("FINANCE_ID").addScalar("FINANCE_NUMBER").addScalar("LOCATION_NAME").addScalar("LOCATION_AREA").addScalar("APPLICATION_DT").addScalar("SPECIFICATION").list();
					for (Object l : datas) {
						Object[] os = (Object[]) l;
						FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(pbwd.getFinanceId());
						if (((BigDecimal) os[0]).compareTo(BigDecimal.ZERO) <= 0) {
							finance.setFinanceState(FinanceStateEnum.REPAYMENTS);
						} else {
							finance.setFinanceState(FinanceStateEnum.PART_REPAYMENTS);
						}
						financeApplicationService.updateFinanceApplication(finance);
						financeApplicationActionApi.initEnterpriseEnterprise(finance.getEnterpriseId());
						financeApplicationService.updateFinanceApplication(finance);
					}
					SessionRepository.closeCurrentSession();
				}
				
				financeApplicationService.updateFinanceApplication(finance1);
				financeApplicationActionApi.initEnterpriseEnterprise(pawd.getEnterpriseId());
			} else if (statement.getStatementSource().equals("QUARTER_SETTLEMENT_MONTH")) {
				MonthEarningDetailEntity mede = monthEarningDetailService.inquiryMonthEarningDetailFinance(statement.getStatementSourceId());
				List<MonthEarningEntity> mees = monthEarningService.inquiryMonthEarningDetail(null, mede.getEnterpriseId(), mede.getYear(), mede.getMonth());
				if (mees != null && mees.size() > 0) {
					MonthEarningEntity mee = mees.get(0);
					mee.setRepaidFee(mee.getRepaidFee().add(statement.getReceiptAmount()));
					if (mee.getRepayingFee().compareTo(mee.getRepaidFee()) == 0) {
						mee.setRepayState(RepayStateEnum.REPAID);
					} else if (mee.getRepayingFee().compareTo(mee.getRepaidFee()) > 0) {
						mee.setRepayState(RepayStateEnum.REPAYING);
					}
					monthEarningService.updateMonthEarning(mee);
				}
			}

			CapitalAccountInfoEntity bank = bankInfoService.inquireBankInfoDetail(params.getAccountInfoId());
			bank.setAccountBalance(bank.getAccountBalance().add(statement.getAmount()));
			bankInfoService.updateBankInfo(bank);

			statement.setBillReceivableId(bre.getBillReceivableId());
			statement.setStatementDate(DateUtils.parseDateInt(params.getWriteoffDateTime()));
			financeMoneyStatementService.renovateFinanceMoneyStatement(statement);
		}

		return writeoffId.toString();
	}

	@Override
	@Transactional
	public String verifiDisbursementMoneyStatement(FinanceWriteoffParams params) {
		BillReceivableEntity be;
		if (params.getBillReceivableId() != null) {
			be = billReceivableService.inquireBillReceivable(params.getBillReceivableId());
			if (params.getWriteoffAmount().compareTo(be.getBalance()) >= 0) {
				throw new BusinessException("余额不足！");
			}
		}
		
		List<FinanceMoneyStatementEntity> statements = new ArrayList<>();
		Map<Long, BigDecimal> receiptAmounts = new HashMap<>();
		if (params.getMoneyStatementId() != null && params.getMoneyStatementId().length > 0) {
			statements = financeMoneyStatementService.inquireFinanceMoneyStatementList(null, FinanceSessionContext.getAccountTenantId(), params.getMoneyStatementId());
			if (statements.size() != params.getMoneyStatementId().length) {
				throw new BusinessException("该帐户下的付款流水与提交的核销流水不一致");
			}
			for (int i = 0; i < params.getMoneyStatementId().length; i++) {
				Long moneyStatementId = params.getMoneyStatementId()[i];
				receiptAmounts.put(moneyStatementId, params.getVerifiAmount()[i]);
			}
		}
		FinanceWriteoffEntity writeoff = FinanceLoanCastor.fromFinanceDisbursementWriteoffParams(params);
		CapitalAccountInfoEntity bankInfo = bankInfoService.inquireBankInfoDetail(writeoff.getAccountInfoId());
		if (bankInfo.getAccountBalance().compareTo(params.getWriteoffAmount()) < 0) {
			throw new BusinessException("该账户余额不足，不能进行核销!");
		}
		bankInfo.setAccountBalance(bankInfo.getAccountBalance().subtract(params.getWriteoffAmount()));
		bankInfo.setAccountLoan(bankInfo.getAccountLoan().add(params.getWriteoffAmount()));
		bankInfoService.updateBankInfo(bankInfo);

		Long writeoffId = financeWriteoffService.createFinanceWriteoff(writeoff);

		List<FinanceWriteoffStatementEntity> writeoffStatements = FinanceLoanCastor.fromFinanceWriteoffParams(writeoff, params);
		for (FinanceWriteoffStatementEntity writeoffStatement : writeoffStatements) {
			financeWriteoffStatementService.createFinanceWriteoffStatement(writeoffStatement);
		}

		// 流水核销
		for (FinanceMoneyStatementEntity statement : statements) {
			// 生成企业收付款记录
			BillReceivableEntity bre;
			if (params.getBillReceivableId() == null) {
				bre = FinanceLoanCastor.toBillReceivableEntity(BillTypeEnum.DISBUREMENT, params);
				bre.setMoneyStatementId(statement.getMoneyStatementId());
				billReceivableService.createBillReceivable(bre);
			} else {
				bre = billReceivableService.inquireBillReceivable(params.getBillReceivableId());
			}
			if (bre.getAmount().compareTo(params.getWriteoffAmount()) >= 0) {
				bre.setBalance(bre.getAmount().subtract(params.getWriteoffAmount()));
			} else {
				throw new BusinessException("余额不足");
			}
			billReceivableService.updateBillReceivable(bre);
			
			// 放款
			if (statement.getStatementSource().equals("LOAN_NOTICE") && statement.getFinanceId() != null) {
				FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(statement.getFinanceId());
				LoanNoticeEntity loan = loanNoticeService.inquireLoanNoticeEntity(statement.getStatementSourceId());
				loan.setLoanAmountAlready(statement.getAmount());
				loan.setLoanDate(DateUtil.todayInt());
				loanNoticeService.renovateLoanNotice(loan);

				// 项目动态
				FinanceProcessEntity processEntity = FinanceProcessCastor.fromFinanceLoanVerify(loan);
				if (!LongUtils.isPrimaryKey(processEntity.getProcessId())) {
					financeProcessService.createFinanceProcess(processEntity);
				} else {
					financeProcessService.renovateFinanceProcess(processEntity);
				}
				processEntity.getCurrentDetail().setProcessId(processEntity.getProcessId());
				financeProcessDetailService.createFinanceProcessDetail(processEntity.getCurrentDetail());
				
				//放款核销时候设置计息日
				Date valueDate = DateUtil.thatDay(new Date()); // 当天开始计息
				Date settlementDate = DateUtils.addDateField(valueDate, Calendar.DATE, -1); // 已结算日期
				// 计算货箱的 可提日期点/罚息日期点/赎货日期点/处置日期点
				Integer advanceTimeLimit = finance.getAdvanceTimeLimit(); // 提前违约期限
				Date pickupableDate = DateUtils.addDateField(valueDate, Calendar.DATE, advanceTimeLimit == null? 0 : advanceTimeLimit); // 可提开始日期-当天可提

				Integer loanTimeLimit = finance.getLoanTimeLimit(); // 借款期限
				Date punishDate = DateUtils.addDateField(valueDate, Calendar.DATE, loanTimeLimit); // 罚息开始日期-当天开始罚息

				Date distrainDate = DateUtils.addDateField(punishDate, Calendar.DATE, 0);

				Date handleDate = DateUtils.addDateField(distrainDate, Calendar.DATE, 0);
				List<ContainerInventoryEntity> inventories = containerInventoryService.inquireContainerInventoryList(finance.getFinanceId(), null);
				for (ContainerInventoryEntity cie : inventories) {
					cie.setValueDate(valueDate);
					cie.setSettlementDate(settlementDate);
					cie.setPickupableDate(pickupableDate);
					cie.setPunishDate(punishDate);
					cie.setDistrainDate(distrainDate);
					cie.setHandleDate(handleDate);
					containerInventoryService.renovateContainerInventory(cie);
					
					FinanceContainerLogEntity fcle = new FinanceContainerLogEntity();
					fcle.setInventoryId(cie.getInventoryId());
					fcle.setOperator(FinanceSessionContext.getAccountFullName());
					fcle.setRemark("放款核销");
					financeContainerLogService.createFinanceContainerLog(fcle);
				}
				
				if (null != finance) {
					finance.setFinanceState(FinanceStateEnum.LOANED);
					finance.setTotalLoanAmount(finance.getTotalLoanAmount().add(params.getWriteoffAmount())); // 设置放款金额
					
					if ((ProductTypeEnum.PURCHASING == finance.getProductType() || ProductTypeEnum.PURCHASING_STORAGE == finance.getProductType()) && finance.getSettlementMethod() == 2) {
						finance.setFinanceState(FinanceStateEnum.LOANED);
					}
					
					financeApplicationService.updateFinanceApplication(finance);
				}
				 
			} else if (statement.getStatementSource().equals("LOANS_MONEY_RETURN")) {
				CapitalAccountInfoEntity bank = bankInfoService.inquireBankInfoDetail(params.getAccountInfoId());
				bank.setAccountAmount(bank.getAccountAmount().subtract(statement.getAmount()));
				bankInfoService.updateBankInfo(bank);
			} else if (statement.getStatementSource().equals("INSURANCE")) {
				InsuranceEntity entity = insuranceService.inquireInsuranceEntity(statement.getStatementSourceId());
				entity.setAlreadyPremium(entity.getAlreadyPremium().add(statement.getAmount()));
				insuranceService.updateFinanceInsurance(entity);
			} else if (statement.getStatementSource().equals("BAIL_RETURN")) {
				FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(statement.getFinanceId());
				
				if ((finance.getBail().subtract(finance.getBailAlreadyReturn())).compareTo(statement.getAmount()) < 0) {
					throw new BusinessException("核销金额超出剩余应退还保证金金额！");
				}
				
				finance.setBailAlreadyReturn(finance.getBailAlreadyReturn().add(statement.getAmount()));
				financeApplicationService.renovateFinanceApplication(finance);
			}

			statement.setDisbursementAmount(statement.getDisbursementAmount().add(params.getWriteoffAmount()));
			if (statement.getCreditQuota() == null) {
				statement.setCreditQuota(BigDecimal.ZERO);
			}
			statement.setDisbursementBalance(statement.getAmount().subtract(statement.getDisbursementAmount()).subtract(statement.getCreditQuota()));
			if (statement.getDisbursementBalance().compareTo(BigDecimal.ZERO) < 0) {
				throw new BusinessException("核销金额不能超过应付金额!");
			}
			if (statement.getDisbursementBalance().compareTo(BigDecimal.ZERO) == 0) {
				statement.setDisbursementVerifiState(Boolean.TRUE);
				statement.setDisbursementVerifiAccount(FinanceSessionContext.getAccountFullName());
				statement.setDisbursementVerifiAccountId(FinanceSessionContext.getAccountId());
				statement.setDisbursementVerifiDateTime(DateUtil.now());
			}
			statement.setStatementDate(DateUtils.parseDateInt(params.getWriteoffDateTime()));
			statement.setBillReceivableId(bre.getBillReceivableId());
			financeMoneyStatementService.renovateFinanceMoneyStatement(statement);
		}
		return writeoffId.toString();
	}
	

	@Override
	@Transactional
	public void callbackMoneyStatement(Long moneyStatementId) {
		FinanceMoneyStatementEntity statement = financeMoneyStatementService.inquireFinanceMoneyStatementDetail(moneyStatementId);
		List<BillReceivableEntity> bres = billReceivableService.inquireBillReceivableList(statement.getMoneyStatementId());
		for (BillReceivableEntity bre : bres) {
			billReceivableService.deleteBillReceivable(bre.getBillReceivableId());
		}
		
		List<FinanceWriteoffStatementEntity> fwses = financeWriteoffStatementService.inquireFinanceWriteoffMoneyStatementList(moneyStatementId);
		for (FinanceWriteoffStatementEntity fwse : fwses) {
			FinanceWriteoffEntity fwe = financeWriteoffService.inquireFinanceWriteoff(fwse.getWriteoffId());
			financeWriteoffService.deleteFinanceWriteoff(fwe.getWriteoffId());
		}
		
		if (statement.getStatementSource().equals("LOAN_NOTICE") && statement.getFinanceId()!=null) {
			FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(statement.getFinanceId());
			LoanNoticeEntity loan = loanNoticeService.inquireLoanNoticeEntity(statement.getStatementSourceId());
			loan.setLoanAmountAlready(loan.getLoanAmountAlready().subtract(statement.getDisbursementAmount()));
			loanNoticeService.renovateLoanNotice(loan);
			
			if (null != finance) {
				finance.setTotalLoanAmount(finance.getTotalLoanAmount().subtract(statement.getDisbursementAmount())); // 设置放款金额
				financeApplicationService.updateFinanceApplication(finance);
			}
		} else if ((statement.getStatementSource().equals("RECEIVABLES") || statement.getStatementSource().equals("RECEIVABLES_WAREHOUSE")) && statement.getFinanceId()!=null) {
			FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(statement.getFinanceId());
			
			if (null != finance) {
				finance.setTotalReceivedAmount(finance.getTotalReceivedAmount().subtract(statement.getReceiptAmount()));//收款金额
				financeApplicationService.updateFinanceApplication(finance);
			}
		}
		
		statement.setBillReceivableId(null);
		
		statement.setDisbursementVerifiState(Boolean.FALSE);
		statement.setDisbursementVerifiAccount(null);
		statement.setDisbursementVerifiAccountId(null);
		statement.setDisbursementVerifiDateTime(null);
		statement.setDisbursementBalance(statement.getAmount());
		statement.setDisbursementAmount(BigDecimal.ZERO);
		
		statement.setReceiptVerifiState(Boolean.FALSE);
		statement.setReceiptVerifiAccount(null);
		statement.setReceiptVerifiAccountId(null);
		statement.setReceiptVerifiDateTime(null);
		statement.setReceiptBalance(statement.getAmount());
		statement.setReceiptAmount(BigDecimal.ZERO);
		
		financeMoneyStatementService.renovateFinanceMoneyStatement(statement);
	}

	@Override
	@Transactional
	public void forceVerifiDisbursementMoneyMoneyStatement(Long moneyStatementId) {
		FinanceMoneyStatementEntity statement = financeMoneyStatementService.inquireFinanceMoneyStatementDetail(moneyStatementId);
		statement.setDisbursementVerifiState(Boolean.TRUE);
		statement.setDisbursementVerifiAccount(FinanceSessionContext.getAccountFullName());
		statement.setDisbursementVerifiAccountId(FinanceSessionContext.getAccountId());
		statement.setDisbursementVerifiDateTime(DateUtil.now());
		financeMoneyStatementService.renovateFinanceMoneyStatement(statement);
	};

	@Override
	@Transactional
	public void forceVerifiReceiptMoneyStatement(Long moneyStatementId) {
		FinanceMoneyStatementEntity statement = financeMoneyStatementService.inquireFinanceMoneyStatementDetail(moneyStatementId);
		statement.setReceiptVerifiState(Boolean.TRUE);
		statement.setReceiptVerifiDateTime(DateUtil.now());
		statement.setReceiptVerifiAccount(FinanceSessionContext.getAccountFullName());
		statement.setReceiptVerifiAccountId(FinanceSessionContext.getAccountId());
		financeMoneyStatementService.renovateFinanceMoneyStatement(statement);
	};

	@Override
	@Transactional
	public void confirmReceiptMoneyStatement(Long moneyStatementId) {
		FinanceMoneyStatementEntity statement = financeMoneyStatementService.inquireFinanceMoneyStatementDetail(moneyStatementId);
		statement.setConfirmState(Boolean.TRUE);
		financeMoneyStatementService.renovateFinanceMoneyStatement(statement);
	}

	@Override
	public PageList<FinanceWriteoffLineInfo> inquireReceiptWriteoffPageList(String writeoffNumber, Date beginDateTime, Date endDateTime, String disbursementName, Long accountInfoId, PageCriteria page) {
		WriteoffTypeEnum writeoffType = WriteoffTypeEnum.RECEIPT;
		Long operatorTenantId = FinanceSessionContext.getAccountTenantId();
		Long receiptTenantId = FinanceSessionContext.getAccountTenantId();
		Long disbursementTenantId = null;
		PageList<FinanceWriteoffEntity> pages = financeWriteoffService.inquireFinanceWriteoffPageList(disbursementTenantId, receiptTenantId, operatorTenantId, writeoffType, writeoffNumber, beginDateTime, endDateTime, null, disbursementName,
				accountInfoId, page);
		PageList<FinanceWriteoffLineInfo> results = new PageList<>(page, pages.getTotalRecordCount());
		for (FinanceWriteoffEntity entity : pages) {
			results.add(FinanceLoanCastor.toFinanceWriteoffLineInfo(entity));
		}
		return results;
	}

	@Override
	public FinanceWriteoffDetail inquireReceiptWriteoffDetail(Long writeoffId) {
		FinanceWriteoffEntity entity = financeWriteoffService.inquireFinanceWriteoff(writeoffId);
		if (!entity.getOperatorTenantId().equals(FinanceSessionContext.getAccountTenantId())) {
			throw new BusinessException("帐户下该流水信息不存在");
		}
		return FinanceLoanCastor.toFinanceWriteoffDetail(entity);
	}

	@Override
	public PageList<FinanceWriteoffLineInfo> inquireDisbursementWriteoffPageList(String writeoffNumber, Date beginDateTime, Date endDateTime, String receiptName, Long accountInfoId, PageCriteria page) {
		WriteoffTypeEnum writeoffType = WriteoffTypeEnum.DISBURSEMENT;
		Long operatorTenantId = FinanceSessionContext.getAccountTenantId();
		Long receiptTenantId = null;
		Long disbursementTenantId = FinanceSessionContext.getAccountTenantId();
		PageList<FinanceWriteoffEntity> pages = financeWriteoffService.inquireFinanceWriteoffPageList(disbursementTenantId, receiptTenantId, operatorTenantId, writeoffType, writeoffNumber, beginDateTime, endDateTime, receiptName, null,
				accountInfoId, page);
		PageList<FinanceWriteoffLineInfo> results = new PageList<>(page, pages.getTotalRecordCount());
		for (FinanceWriteoffEntity entity : pages) {
			results.add(FinanceLoanCastor.toFinanceWriteoffLineInfo(entity));
		}
		return results;
	}

	@Override
	public FinanceWriteoffDetail inquireDisbursementWriteoffDetail(Long writeoffId) {
		FinanceWriteoffEntity entity = financeWriteoffService.inquireFinanceWriteoff(writeoffId);
		if (!entity.getOperatorTenantId().equals(FinanceSessionContext.getAccountTenantId())) {
			throw new BusinessException("帐户下该流水信息不存在");
		}
		return FinanceLoanCastor.toFinanceWriteoffDetail(entity);
	}

	@Override
	public String createBillReceivable(String disbursementBank, String disbursementCreditCard, String disbursementName, String drawee, String receiptBank, String receiptName, String receiptCreditCard, String payee, String writeoffRemark,
			BigDecimal amount, String writeoffNumber, Integer billType, String fileUuids, Long loansMoneyId) {
		BillReceivableEntity entity = new BillReceivableEntity();
		entity.setDisbursementBank(disbursementBank);
		entity.setDisbursementCreditCard(disbursementCreditCard);
		entity.setDisbursementName(disbursementName);
		entity.setDrawee(drawee);
		entity.setReceiptBank(receiptBank);
		entity.setReceiptCreditCard(receiptCreditCard);
		entity.setReceiptName(receiptName);
		entity.setPayee(payee);
		entity.setAmount(amount);
		entity.setBalance(amount);
		entity.setWriteoffNumber(writeoffNumber);
		entity.setFileUuid(fileUuids);
		entity.setOperator(FinanceSessionContext.getAccountFullName());
		entity.setOperatorId(FinanceSessionContext.getAccountId());
		entity.setBillType(BillTypeEnum.valueOf(billType));
		entity.setLoansMoneyId(loansMoneyId);
		entity.setWriteoffRemark(writeoffRemark);

		billReceivableService.createBillReceivable(entity);
		return entity.getBillReceivableId().toString();
	}

	@Override
	public BillReceivableDetail inquireBillReceivableDetail(Long billReceivableId) {
		BillReceivableEntity entity = billReceivableService.inquireBillReceivable(billReceivableId);
		BillReceivableDetail detail = new BillReceivableDetail();
		BeanUtils.copyProperties(entity, detail);

		FinanceMoneyStatementEntity fse = financeMoneyStatementService.inquireFinanceMoneyStatementDetail(entity.getMoneyStatementId());
		if (fse != null) {
			detail.getFinanceMoneyStatementList().add(FinanceLoanCastor.toFinanceMoneyStatement(fse));
		}

		return detail;
	}

	@Override
	public PageList<BillReceivableDetail> inquireBillReceivablePageList(Integer billType, Date startDate, Date endDate, String writeoffNumber, String payee, String drawee, Long moneyStatementId, PageCriteria page) {
		PageList<BillReceivableEntity> pages = billReceivableService.inquireBillReceivablePageList(BillTypeEnum.valueOf(billType), startDate, endDate, writeoffNumber, payee, drawee, moneyStatementId, page);
		PageList<BillReceivableDetail> results = new PageList<>(page, pages.getTotalRecordCount());
		for (BillReceivableEntity entity : pages) {
			BillReceivableDetail detail = new BillReceivableDetail();
			BeanUtils.copyProperties(entity, detail);
//			List<FinanceMoneyStatementEntity> lists = financeMoneyStatementService.inquireFinanceMoneyStatementBillReceivableList(entity.getBillReceivableId());
//			for (FinanceMoneyStatementEntity fse : lists) {
//				detail.getFinanceMoneyStatementList().add(FinanceLoanCastor.toFinanceMoneyStatement(fse));
//			}
			results.add(detail);
		}
		return results;
	}

	@Override
	public PageList<Capital> inquireCapitalPageList(String financeNumber, String enterpriseName, Date startDate, Date endDate, PageCriteria page) {
		PageList<FinanceApplicationEntity> pageList = financeApplicationService.inquireFinancePageList(financeNumber, enterpriseName, startDate, endDate, page);
		PageList<Capital> resultList = new PageList<>(page, pageList.getTotalRecordCount());
		for (FinanceApplicationEntity entity : pageList) {
			Capital info = new Capital();
			FinanceLoanCastor.toFinanceCapitalInfo(entity, info);
			resultList.add(info);
		}
		return resultList;
	}

	@Override
	public void exportCapitalExcel() {
		List<FinanceApplicationEntity> pageList = financeApplicationService.inquireFinanceList(null, null, null, null, null);
		List<Capital> resultList = new ArrayList<>();
		for (FinanceApplicationEntity entity : pageList) {
			Capital info = new Capital();
			FinanceLoanCastor.toFinanceCapitalInfo(entity, info);
			resultList.add(info);
		}
		CreateSimpleExcelToDisk.createSimpleExcelToDisk("资金台账", new String[]{"客户名称", "融资产品", "融资单号", "批复日期", "借款周期", "融资金额", "已放款总金额", "未放款总金额", "应收融资款总额", "已收融资款总额", "未收融资款总额", "应收利息总额", "已收利息总额", "待收利息总额", "应收保证金总额", "已收保证金总额", "追加保证金总额", "追加保证金已收", "已退保证金总额", "保险应收总额", "保险已收总额", "保险应付总额", "保险已付总额", "其他应收总额", "其他已收总额", "其他应付总额", "其他已付总额"}, resultList);
	}

	@Override
	public String createFinanceOtherMoneyStatement(FinanceOtherMoneyStatement statement) {
		FinanceOtherMoneyStatementEntity fomse = new FinanceOtherMoneyStatementEntity();
		BeanUtils.copyProperties(statement, fomse);
		financeOtherMoneyStatementService.createFinanceOtherMoneyStatement(fomse);
		return fomse.getOtherMoneyStatementId().toString();
	}

	@Override
	public void updateFinanceOtherMoneyStatement(FinanceOtherMoneyStatement statement) {
		FinanceOtherMoneyStatementEntity fomse = financeOtherMoneyStatementService.inquireFinanceOtherMoneyStatement(statement.getOtherMoneyStatementId());
		BeanUtils.copyProperties(statement, fomse);
		financeOtherMoneyStatementService.updateFinanceOtherMoneyStatement(fomse);
	}

	@Override
	public PageList<FinanceOtherMoneyStatement> inquireFinanceOtherMoneyStatementPageList(PageCriteria page) {
		PageList<FinanceOtherMoneyStatementEntity> pages = financeOtherMoneyStatementService.inquireFinanceOtherMoneyStatementPageList(page);
		PageList<FinanceOtherMoneyStatement> results = new PageList<>(page, pages.getTotalRecordCount());
		for (FinanceOtherMoneyStatementEntity fomse : pages) {
			FinanceOtherMoneyStatement foms = new FinanceOtherMoneyStatement();
			BeanUtils.copyProperties(fomse, foms);
			results.add(foms);
		}
		return results;
	}

	@Override
	public void confirmFinanceOtherMoneyStatement(Long otherMoneyStatementId) {
		FinanceOtherMoneyStatementEntity fomse = financeOtherMoneyStatementService.inquireFinanceOtherMoneyStatement(otherMoneyStatementId);
		fomse.setConfirmState(Boolean.TRUE);
		financeOtherMoneyStatementService.updateFinanceOtherMoneyStatement(fomse);
		FinanceMoneyStatementEntity statement = FinanceLoanCastor.fromOtherStatement(fomse);
		financeMoneyStatementService.createFinanceMoneyStatement(statement);
	}

	@Override
	public FinanceOtherMoneyStatement inquireFinanceOtherMoneyStatement(Long otherMoneyStatementId) {
		FinanceOtherMoneyStatementEntity fomse = financeOtherMoneyStatementService.inquireFinanceOtherMoneyStatement(otherMoneyStatementId);
		FinanceOtherMoneyStatement foms = new FinanceOtherMoneyStatement();
		BeanUtils.copyProperties(fomse, foms);
		return foms;
	}
}
